Lodash group array by key - javascript

I have the following JSON Structure:
{
"list":[
{
"id":"7ccba2c3-e6df-4cb2-94b9-2f6320366ce0",
"name":"List 1",
"people":[
{"id":"b6cb6317-8f89-4826-b60b-aa0ecf51b1af","name":"Person 1","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]},
{"id":"f2620c63-37cc-45be-86e0-fff5d415e483","name":"Person 2","mediaAccounts":[{"socialNetwork":"twitter"},{"socialNetwork":"facebook"}]},
{"id":"e8ccae28-6695-435b-ba61-dbf569e75665","name":"Person 3","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]}
]
},
{
"id":"a2d1d55a-e6df-4cb2-94b9-000000011212",
"name":"List 2",
"people":[
{"id":"b6cb6317-8f89-4826-b60b-aa0ecf51b1af","name":"Person 4","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]},
{"id":"f2620c63-37cc-45be-86e0-fff5d415e483","name":"Person 5","mediaAccounts":[{"socialNetwork":"twitter"},{"socialNetwork":"facebook"}]},
{"id":"e8ccae28-6695-435b-ba61-dbf569e75665","name":"Person 6","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]}
]
}
]
}
and I need to group people in a only one array like this:
{
"people": [
{"id":"b6cb6317-8f89-4826-b60b-aa0ecf51b1af","name":"Person 1","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]},
{"id":"f2620c63-37cc-45be-86e0-fff5d415e483","name":"Person 2","mediaAccounts":[{"socialNetwork":"twitter"},{"socialNetwork":"facebook"}]},
{"id":"e8ccae28-6695-435b-ba61-dbf569e75665","name":"Person 3","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]},
{"id":"b6cb6317-8f89-4826-b60b-aa0ecf51b1af","name":"Person 4","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]},
{"id":"f2620c63-37cc-45be-86e0-fff5d415e483","name":"Person 5","mediaAccounts":[{"socialNetwork":"twitter"},{"socialNetwork":"facebook"}]},
{"id":"e8ccae28-6695-435b-ba61-dbf569e75665","name":"Person 6","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]}
]
}
using underscore groupBy function, the return remains the same.
Anyone has any idea how can I group this content above?
Thanks in advance.

You can use Array.flatMap() (or lodash's _.flatMap()) to flatten the list of people to as single array:
const data = {"list":[{"id":"7ccba2c3-e6df-4cb2-94b9-2f6320366ce0","name":"List 1","people":[{"id":"b6cb6317-8f89-4826-b60b-aa0ecf51b1af","name":"Person 1","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]},{"id":"f2620c63-37cc-45be-86e0-fff5d415e483","name":"Person 2","mediaAccounts":[{"socialNetwork":"twitter"},{"socialNetwork":"facebook"}]},{"id":"e8ccae28-6695-435b-ba61-dbf569e75665","name":"Person 3","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]}]},{"id":"a2d1d55a-e6df-4cb2-94b9-000000011212","name":"List 2","people":[{"id":"b6cb6317-8f89-4826-b60b-aa0ecf51b1af","name":"Person 4","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]},{"id":"f2620c63-37cc-45be-86e0-fff5d415e483","name":"Person 5","mediaAccounts":[{"socialNetwork":"twitter"},{"socialNetwork":"facebook"}]},{"id":"e8ccae28-6695-435b-ba61-dbf569e75665","name":"Person 6","mediaAccounts":[{"socialNetwork":"facebook"},{"socialNetwork":"twitter"}]}]}]}
const result = {
people: data.list.flatMap(o => o.people)
}
console.log(result)

Related

Normal Mapping vs Reduce

I'm trying to convert an object into single array with just key and value. I tried two different ways. Though I succeeded in my first attempt but using reduce I am unable to get the result. Please kindly let me know if there is/are better ways of achieving the same. Thank you.
var demoArr = [
{
"results": [
{
"listing_id": 10544193
},
{
"listing_id": 4535435
}
],
"results1": [
{
"listing_id": 1054419363
},
{
"listing_id": 432535435
}
]
}
];
let aaa = [];
// demoArr.map(x => { (before)
demoArr.forEach(x => { //(after)
let ss = Object.values(x);
// ss.map(y => { (before)
ss.forEach(y => { //(after)
y.forEach(k => {
aaa.push({"listing_id" : k.listing_id});
})
});
});
Resulted in the following.
[{"listing_id":10544193},{"listing_id":4535435},{"listing_id":1054419363},{"listing_id":432535435}]
Is there a better way to achieve the above? Maybe by using reduce? I tried but failed to get the result.
var ds = demoArr.reduce((a,value) => {
a[value.listing_id] = a[value.listing_id] ? a[value.listing_id] : value
return a
},{});
Here's one way use flatMap() and Object.values, then flatten the result. Using Object.values as an argument in this fashion is a shorthand for applying the map argument directly into the Object.values method and returning the result
var demoArr = [{
"results": [{
"listing_id": 10544193
},
{
"listing_id": 4535435
}
],
"results1": [{
"listing_id": 1054419363
},
{
"listing_id": 432535435
}
]
}];
let output = demoArr.flatMap(Object.values).flat();
console.log(output)

Looking for a way to merge Javascript Object keys inside array, only on matching Ids. Map? flatmap?

Looking for a way to merge Javascript Object keys inside array, only on matching Ids. Should i use Map? or flatmap?
I have
const districtList =[
{ id:'1234blah', companyId:'09871345', districtName:'abc1' },
{ id:'2341blah', companyId:'87134590', districtName:'abc2' },
{ id:'3412blah', companyId:'09134587', districtName:'abc3' },
]
and
const companyList =[
{id:'09871345', companyName:'CompanyOne', info:'some' },
{id:'87134590', companyName:'CompanyTwo', info:'stuff' },
{id:'09134587', companyName:'CompanyThree', info:'todo' },
]
But what i want is the data from the company array inside the district array, to get the missing company name, and other info.
const improvedDistrictList =[
{ id:'1234blah', companyId:'09871345', districtName:'abc1', companyName:'CompanyOne', info:'some' },
{ id:'2341blah', companyId:'87134590', districtName:'abc2', companyName:'CompanyTwo', info:'stuff' },
{ id:'3412blah', companyId:'09134587', districtName:'abc3', companyName:'CompanyThree', info:'todo' },
]
I would map through the district list, find a corresponding company for each one based on the companyId and then just add more fields to the new array with one caveat: it looks like your companyList array may or may not contain companyName. As such:
const districtList =[
{id:'1234blah',companyId:'09871345', districtName:'abc1'},
{id:'2341blah',companyId:'87134590', districtName:'abc2'},
{id:'3412blah',companyId:'09134587', districtName:'abc3'},
]
const companyList =[
{id:'09871345',companyName:'CompanyOne', info:'some'},
{id:'87134590',companyId:'CompanyTwo', info:'stuff'},
{id:'09134587',companyId:'CompanyThree', info:'todo'},
]
const result = districtList.map(item => {
const company = companyList.find(c => c.id === item.companyId);
return {...item, [company.companyName ? 'companyName' : 'companyId']: company.companyName ? company.companyName : company.companyId, info: company.info }
})
console.log(result)
Also, as pointed out in the comments, you won't end up with 2 companyId keys in the resulting array as the latter will override the former.
this way...
const districtList =[
{ id:'1234blah', companyId:'09871345', districtName:'abc1' },
{ id:'2341blah', companyId:'87134590', districtName:'abc2' },
{ id:'3412blah', companyId:'09134587', districtName:'abc3' },
]
const companyList =[
{id:'09871345', companyName:'CompanyOne', info:'some' },
{id:'87134590', companyName:'CompanyTwo', info:'stuff' },
{id:'09134587', companyName:'CompanyThree', info:'todo' },
]
const improvedDistrictList = companyList.map(cl=>
({...cl,...districtList.find(x=>x.companyId===cl.id)}))
console.log( improvedDistrictList )
.as-console-wrapper { max-height: 100% !important; top: 0; }

Push values from nested objects

I would like to know the best method for grabbing values from nested objects like this one:
var object = {
1: {
1: {
"names": "bob"
},
2: {
"names": "jim"
}
}
}
What function or loop would I write to push the values “bob” and “Jim” into an array?
Thank you in advance!
you can use Object.values + map
Object.values(object[1]).map(p => p.names)

Convert Objects to array in angularjs

I have this data:
$scope.data = [
{
data1:"1",
data2:"2"
},
{
data1:"1",
data2:"2"
}
];
I want to output them in console log as:
[ [1,2], [1,2] ]
Any suggestions please.
$scope.data = [{
data1:"1",
data2:"2"
}, {
data1:"1",
data2:"2"
}].map(function (o) {
return [o.data1, o.data2];
// or, if you really need the items to be numbers:
// return [o.data1, o.data2].map(Number);
});
Yao,
Look at Lodash or ngLodash. Lodash has lots of function that do exactly what you are looking to do. ngLodash is a fork and AngularJS rewrite of Lodash.
https://github.com/rockabox/ng-lodash
https://lodash.com
Hope this helps!
Regards,
Jeff

Underscore recursive groupBy array of string arrays

I'm trying to combine and group an array with a bunch of flat arrays that contain only strings, no objects.
So my array looks something like this:
var array = [
["MotherNode", "Node1", "ChildNode1", "ChildOfChildNode1"],
["MotherNode", "Node1", "ChildNode2", "ChildOfChildNode2"],
["MotherNode", "Node2", "ChildNode3", "ChildOfChildNode3"],
["MotherNode", "Node2", "ChildNode3", "ChildOfChildNode4"],
["MotherNode", "Node3", "ChildNode4", "ChildOfChildNode5"],
["MotherNode", "Node3", "ChildNode4", "ChildOfChildNode5"]
]
Im doing this in javascript/angularjs and so far I've gathered that the best solution is probably to use underscore.js groupBy/combine methods. However most of the examples that i can find are dealing with arrays of objects where they can group them together by using a value's key. And I'm not good enough with algorithms yet to be able to figure this out on my own.
The array I'm dealing with can have hundreds of values and the result array could get 5-10 levels deep.
The result I'd like by parsing the above array would look something like this:
var result= {
"MotherNode": [{
"Node1":[{
"ChildNode1":"ChildOfChildNode1"
},{
"ChildNode2":"ChildOfChildNode2"
},{
"Node2":[{
"ChildNode3":["ChildOfChildNode3","ChildOfChildNode4"]
},{
"Node3":[{
"ChildNode4":"ChildOfChildNode5"
}
]
}
So does anyone have any clue how this can be done? I'm completely out of ideas.
I solved this using _.reduce grouping wasnt the way to go
var result = _.reduce(array,function(memo, val){
var tmp = memo;
_.each(val, function(fldr){
if(!_.has(tmp, fldr)){
tmp[fldr] = {}
}
tmp = tmp[fldr]
})
return memo
},{})
the end leaf wont be set as a value but it should be easy to change that behavior to whatever suits you use case
{ MotherNode:
{ Node1:
{ ChildNode1: { ChildOfChildNode1: {} },
ChildNode2: { ChildOfChildNode2: {} } },
Node2: { ChildNode3: { ChildOfChildNode3: {}, ChildOfChildNode4: {} } },
Node3: { ChildNode4: { ChildOfChildNode5: {} } } } }

Categories