Nested array filtering in lodash - javascript

I have a Json Like this -
[
{
"place": 1,
"player": {
"playerId": 733234,
"firstName": "cheng",
"lastName": "w",
"country": {
"countryId": 13,
"name": "China",
"abbreviation": "CHN"
}
},
"rounds": [
{
"roundNumber": 1,
"startHole": 1
},
{
"roundNumber": 2,
"startHole": 10,
},
{
"roundNumber": 3,
"startHole": -1,
"courseId": 950
},
{
"roundNumber": 4,
"startHole": -1,
"courseId": 950
}
]
},
{
"place": 2,
"player": {
"playerId": 392990,
"firstName": "Matt",
"lastName": "Harmon",
"country": {
"countryId": 1,
"name": "United States",
"abbreviation": "USA"
}
},
"rounds": [
{
"roundNumber": 1,
"startHole": 1
},
{
"roundNumber": 2,
"startHole": 10,
}
]
}
]
I need to filter and create a new json using Lodash in the below format. I tried _.filter but always I am getting undefined error
{
rounds: [
[
{
player Name: "cheng",
roundNumber: 1
starthole: 1
},
{
player Name: "math",
roundNumber: 1
starthole: 1
}
],
[
{
roundNumber: 2
player Name: "cheng",
starthole: 2
},
{
roundNumber: 2
player Name: "math",
starthole: 2
}
]
]
}
Is there any way to restructure the Json to new format using lodash and Javascript

You dont need filter. You need mapping as you are reformatting.
You can chain map and flatten. In Your case
let modifiedArray=_(YOURARRAYHERE).map(s=>{
let x=_.map(s.rounds,a=>{
return {
roundNumber:a.roundNumber,
startHole:a.startHole,
playerName:s.player.firstName
}
});
return x;
}).flatten().value();

Related

javascript extract and convert into new array

I have the following array
[ {
"contactId": "a87d096gd5fuop",
"firstName": "John Doe",
"registrationTypes": {
"selectedOptions": [
{
}
],
"subTotal": 1620.003
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"events": {
"selectedOptions": [
{
"id": "1",
"name": "T1",
"value": "4550006:3",
},
{
"id": "2",
"name": "T2",
"value": "4550005:3",
},
{
"id": "3",
"name": "T3",
"value": "4550003:3",
}
],
"subTotal": 135.003
},
"freeNetworkingFunctions": {
},
"total": 1755.0059999999999
},
{
"contactId": "a097f",
"firstName": "David",
"registrationTypes": {
"selectedOptions": [
{}
],
"subTotal": 899.998
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"member": {
"selectedOptions": [
{
}
],
"subTotal": 228.8
},
"events": {
"selectedOptions": [
{
"id": "4",
"name": "T4",
"value": "4550002:2",
},
{
"id": "5",
"name": "T5",
"value": "4550001:2",
},
{
"id": "6",
"name": "T6",
"value": "4550003:2",
}
],
"subTotal": 135.003
},
"total": 1263.801
}
]
From the above array, I want to extract events, loop all the data and get only values. So my new array should be something like this:
[ {
"contactId": "a87d096gd5fuop",
"firstName": "John Doe",
"registrationTypes": {
"selectedOptions": [
{
}
],
"subTotal": 1620.003
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"events": [
"4550006:3"
"4550005:3",
"4550003:3",
],
},
"freeNetworkingFunctions": {
},
"total": 1755.0059999999999
},
{
"contactId": "a097f",
"firstName": "David",
"registrationTypes": {
"selectedOptions": [
{}
],
"subTotal": 899.998
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"member": {
"selectedOptions": [
{
}
],
"subTotal": 228.8
},
"events": [
"4550004:2"
"4550008:3",
"4550003:3",
],
"subTotal": 135.003
},
"total": 1263.801
}
]
So it should return the original array, however, events value data should be in one array.
var arr = [];
var r(var i=0;i<data.length;i++){
data.push(arr[i].value);
}
var newData = [...data, arr]
However, this doesn't work. Any help would be highly appreciated.
Use map twice - once on the dataset to iterate over the objects, and within that map to get an array of values from the selectedOptions.
const data=[{contactId:"a87d096gd5fuop",firstName:"John Doe",registrationTypes:{selectedOptions:[{}],subTotal:1620.003},foo1:{selectedOptions:[],subTotal:0},events:{selectedOptions:[{id:"1",name:"T1",value:"4550006:3"},{id:"2",name:"T2",value:"4550005:3"},{id:"3",name:"T3",value:"4550003:3"}],subTotal:135.003},freeNetworkingFunctions:{},total:1755.0059999999999},{contactId:"a097f",firstName:"David",registrationTypes:{selectedOptions:[{}],subTotal:899.998},foo1:{selectedOptions:[],subTotal:0},member:{selectedOptions:[{}],subTotal:228.8},events:{selectedOptions:[{id:"4",name:"T4",value:"4550002:2"},{id:"5",name:"T5",value:"4550001:2"},{id:"6",name:"T6",value:"4550003:2"}],subTotal:135.003},total:1263.801}];
const out = data.map(obj => {
// Destructure the selected options from the
// rest of each object
const { events: { selectedOptions }, ...rest } = obj;
// `map` over the options to just get an array of values
const events = selectedOptions.map(option => {
return option.value;
});
// Return a new object with the new events property
// combined with the other properties again
return { ...rest, events };
});
console.log(out);
Additional documentation
Destructuring assignment
Rest parameters
Spread syntax

Filter complex array in react native?

I have array .
const arr = [{
"status": "success",
"data": [{
"name": "user1",
"games": [{
"id": 1,
"gamename": "cricket"
}, {
"id": 2,
"gamename": "football"
}]
},
{
"name": "user1",
"games": [{
"id": 1,
"gamename": "videogames"
}, {
"id": 2,
"gamename": "volleyball"
}]
}
]
}]
I tried following the code to filter it. and no output show
arr.map((item,idx) => (
console.log(item.data.games.gamename)
)
))
I want to print all game name eg.
cricket
football
videogames
volleyball
We can use flatMap() to do it
const arr = [{
"status": "success",
"data": [{
"name": "user1",
"games": [{
"id": 1,
"gamename": "cricket"
}, {
"id": 2,
"gamename": "football"
}]
},
{
"name": "user1",
"games": [{
"id": 1,
"gamename": "videogames"
}, {
"id": 2,
"gamename": "volleyball"
}]
}
]
}]
// multiple flatMap chain invocation seems ugly,waiting for more elegant solution
let result = arr.flatMap(a => a.data).flatMap(a => a.games).flatMap(a => a.gamename)
console.log(result)
Data is a array and so is games:
const arr = [
{
status: "success",
data: [
{
name: "user1",
games: [
{
id: 1,
gamename: "cricket",
},
{
id: 2,
gamename: "football",
},
],
},
{
name: "user1",
games: [
{
id: 1,
gamename: "videogames",
},
{
id: 2,
gamename: "volleyball",
},
],
},
],
},
];
arr.map((item) => {
item.data.map((item) => {
item.games.map((item) => {
console.log(item.gamename);
});
});
});
Try out this code, it will return only game names, you can change the join if don't need comma (,)
Output :
"cricket,football,videogames,volleyball"
const arr = [{
"status": "success",
"data": [{
"name": "user1",
"games": [{
"id": 1,
"gamename": "cricket"
}, {
"id": 2,
"gamename": "football"
}]
},
{
"name": "user1",
"games": [{
"id": 1,
"gamename": "videogames"
}, {
"id": 2,
"gamename": "volleyball"
}]
}
]
}];
console.log(JSON.stringify(arr.filter(e=>e.status=="success").map(e=>e.data.map(f=>f.games.map(g=>g.gamename)).join(",")).join(",")));

format object array to grouped nested array object to generate antd tree table

I get the following array object from response and I need to implement antd tree table in my react application using this array object.
const students=[
{
"index": "5260574",
"studentName": "David Sinclair",
"marks": "177",
"gender": "M",
"resultId": 16,
"province": {
"code": "1",
"name": "Andregan"
},
"county": {
"name": "Silk",
"code": "21"
},
"city": {
"code": "234",
"name": "Meegan"
},
"rural": {
"code": "41",
"name": "Thumphil"
},
"canEvaluate": true
},
{
"index": "5259991",
"studentName": "KALURA GEETH DAMS",
"marks": "177",
"gender": "M",
"resultId": 17,
"province": {
"code": "1",
"name": "Andregan"
},
"county": {
"name": "Silk",
"code": "21"
},
"city": {
"code": "234",
"name": "Meegan"
},
"rural": {
"code": "41",
"name": "Thumphil"
},
"canEvaluate": true
},
{
"index": "5260534",
"studentName": "Mathew Jenkins",
"marks": "157",
"gender": "M",
"resultId": 21,
"province": {
"code": "1",
"name": "Andregan"
},
"county": {
"name": "Silk",
"code": "21"
},
"city": {
"code": "44",
"name": "Wrens"
},
"rural": {
"code": "49",
"name": "Cardin"
},
"canEvaluate": true
},
{
"index": "5260680",
"studentName": "MEDIW KENULA",
"marks": "177",
"gender": "M",
"resultId": 18,
"province": {
"code": "2",
"name": "Kiren"
},
"county": {
"name": "Georgia",
"code": "23"
},
"city": {
"code": "34",
"name": "Eden Hill"
},
"rural": {
"code": "99",
"name": "Southern Sea"
},
"canEvaluate": true
}
]
I want to group this response as province , county, city, rural wise as shown in below rendered antd tree table.
.
To get above tree table and get selected students, I need to format the response as below for the dataSource.
Expected output is as below.
const data = [
{
key: '1',
name: 'Andregan',
resultCount: 3,
resultIds: [16, 17, 21],
children: [
{
key: '21',
name: 'Silk',
resultCount: 2,
resultIds: [16, 17, 21],
children: [
{
key: '234',
name: 'Meegan',
resultCount: 2,
resultIds: [16, 17],
children: [
{
key: '41',
name: 'Thumphil',
resultCount: 2,
resultIds: [16, 17],
},
],
},
{
key: '44',
name: 'Wrens',
resultCount: 1,
resultIds: [21],
children: [
{
key: '49',
name: 'Cardin',
resultCount: 1,
resultIds: [21],
},
],
},
],
},
],
},
{
key: '2',
name: 'Kiren',
resultCount: 1,
resultIds: [18],
children: [
{
key: '23',
name: 'Georgia',
resultCount: 1,
resultIds: [18],
children: [
{
key: '34',
name: 'Eden Hill',
resultCount: 1,
resultIds: [18],
children: [
{
key: '99',
name: 'Southern Sea',
resultCount: 1,
resultIds: [18],
},
],
},
],
},
],
},
];
Can anyone suggest how to format response to above format to achieve this? Thank you.

Nested Array Filter/Mapping

Probably a basic question, but I've been blocked for a day now on this.
I am trying to get the correct map/filter from the following array:
[{
"id": 1,
"description": "Electric",
"subUtilityTypes": [{
"id": 5,
"description": "Grid"
},
{
"id": 6,
"description": "Solar"
}
]
},
{
"id": 2,
"description": "Gas",
"subUtilityTypes": [{
"id": 7,
"description": "Heating Oil"
},
{
"id": 8,
"description": "Natural Gas"
},
{
"id": 11,
"description": "Propane"
}
]
}
]
I want to get the id and description inside all subUtilityTypes.
This is what I've been trying:
this.options = arr1.map((parent) => {
return {
id: parent.id,
name: parent.subUtilityTypes.flatMap((child) => {
return child.description;
})
};
});
My problem with what I am trying is that instead of creating separate objects I am getting parent id and list of child names like this:
[{
"id": 1,
"name": [
"Grid",
"Solar"
]
},
{
"id": 2,
"name": [
"Heating Oil",
"Natural Gas",
"Propane"
]
}
]
Expected result should look like this:
[{
"id": 5,
"name": [
"Grid"
]
},
{
"id": 6,
"name": [
"Solar"
]
},
{
"id": 7,
"name": [
"Heating Oil"
]
}
]
Firstly use flatMap to get subUtilityTypes, then map entries:
const input = [{id:1,description:"Electric",subUtilityTypes:[{id:5,description:"Grid"},{id:6,description:"Solar"}]},{id:2,description:"Gas",subUtilityTypes:[{id:7,description:"Heating Oil"},{id:8,description:"Natural Gas"},{id:11,description:"Propane"}]}];
const res = input.flatMap(e => e.subUtilityTypes)
.map(e => ({ id: e.id, name: [e.description] }))
console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore this */
Map only arr1 by returning only subUtilityTypes and then map it to get the desired result :
arr1.flatMap(item=>item.subUtilityTypes)
.map(item=>({id:item.id,name:[item.description]}))
let arr1=[
{
"id": 1,
"description": "Electric",
"subUtilityTypes": [
{
"id": 5,
"description": "Grid"
},
{
"id": 6,
"description": "Solar"
}
]
},
{
"id": 2,
"description": "Gas",
"subUtilityTypes": [
{
"id": 7,
"description": "Heating Oil"
},
{
"id": 8,
"description": "Natural Gas"
},
{
"id": 11,
"description": "Propane"
}
]
}
]
let options=arr1.flatMap(item=>item.subUtilityTypes).map(item=>({id:item.id,name:[item.description]}))
console.log(options)
You can also use reduce to achieve the same result.
arr.reduce((acc, curr) => [...acc,...curr.subUtilityTypes.map((o) => ({ id: o.id, name: [o.description] })),],[])
const arr = [
{
id: 1,
description: "Electric",
subUtilityTypes: [
{
id: 5,
description: "Grid",
},
{
id: 6,
description: "Solar",
},
],
},
{
id: 2,
description: "Gas",
subUtilityTypes: [
{
id: 7,
description: "Heating Oil",
},
{
id: 8,
description: "Natural Gas",
},
{
id: 11,
description: "Propane",
},
],
},
];
const result = arr.reduce((acc, curr) => [...acc,...curr.subUtilityTypes.map((o) => ({ id: o.id, name: [o.description] })),],[]);
console.log(result);

Normalizing Nested Many To Many

I am looking to find a way to normalize nested many to many relationships.
However, it has been going when the model is a few levels deep, such as Categories in the example below. In the output the location id 27 only contains category ids 1 and 7 (which I assume is because that is what the last version of location 27 shows). What is the best approach in normalizing this type of data?
Would using shop id in the location be a good idea? i.e.
"locations": {
"1-27": {
"id": 27,
"label": "Birmingham",
"categories": [
1,
2,
7
]
},
"2-27": {
"id": 27,
"label": "Birmingham",
"categories": [
1,
7
]
}
},
Thanks for taking the time to read this!
Additional Data Details
Database
Shops
id
label
Locations
id
label
Location_Shop
location_id
shop_id
Categories
id
label
Category_Location
category_id
location_id
Example Data
[
{
id: 1,
label: 'First Shop',
locations: [
{
id: 27,
label: 'Birmingham',
categories: [
{
id: 1,
label: 'Car Park',
},
{
id: 2,
label: 'Petrol Station',
},
{
id: 7,
label: 'Bakery',
},
],
},
],
},
{
id: 2,
label: 'Second Shop',
locations: [
{
id: 27,
label: 'Birmingham',
categories: [
{
id: 1,
label: 'Car Park',
},
{
id: 7,
label: 'Bakery',
},
],
},
],
},
]
Code
const categorySchema = new schema.Entity('categories');
const locationSchema = new schema.Entity('locations', {
categories: [categorySchema],
});
const shopSchema = new schema.Entity('shops', {
locations: [locationSchema],
});
Output
{
"entities": {
"categories": {
"1": {
"id": 1,
"label": "Car Park"
},
"2": {
"id": 2,
"label": "Petrol Station"
},
"7": {
"id": 7,
"label": "Bakery"
}
},
"locations": {
"27": {
"id": 27,
"label": "Birmingham",
"categories": [
1,
7
]
}
},
"shops": {
"1": {
"id": 1,
"label": "First Shop",
"locations": [
27
]
},
"2": {
"id": 2,
"label": "Second Shop",
"locations": [
27
]
}
}
},
"result": [
1,
2
]
}

Categories