Looping through array within an array to determine value - javascript

I need to loop through the following array using a for loop and determine if the persons age is 18 and over, or if they are under 18 and log a string accordingly.
Ive been trying a few different things like this:
var peopleWhoWantToSeeMadMaxFuryRoad = [
{
name: "Mike",
age: 12,
gender: "male"
},{
name: "Madeline",
age: 80,
gender: "female"
},{
name: "Cheryl",
age: 22,
gender: "female"
},{
name: "Sam",
age: 30,
gender: "male"
},{
name: "Suzy",
age: 4,
gender: "female"
}
]
for(var i = 0; i < peopleWhoWantToSeeMadMaxFuryRoad.length; i++){
for(var j = 0; j < peopleWhoWantToSeeMadMaxFuryRoad[i].length; j++){
if (j == 'number' && j < 18){
console.log("person is under 18")
}
}
}
But I cant seem to get it . Any help would be appreciate

No need for a double for loop, you can achieve this with a single for loop:
for(var i = 0; i < peopleWhoWantToSeeMadMaxFuryRoad.length; i++){
if(peopleWhoWantToSeeMadMaxFuryRoad[i].age < 18) {
// Do something for underaged people;
} else {
// Do something for people over 18
}
}
Or you can use the foreach loop:
peopleWhoWantToSeeMadMaxFuryRoad.forEach(function(person) {
if(person.age < 18) {
// Do something for underaged people;
} else {
// Do something for people over 18
}
});

Objects don't have a meaningful length. If you want to extract the age property, do that explicitly, eg obj.age:
var peopleWhoWantToSeeMadMaxFuryRoad = [{
name: "Mike",
age: 12,
gender: "male"
}, {
name: "Madeline",
age: 80,
gender: "female"
}, {
name: "Cheryl",
age: 22,
gender: "female"
}, {
name: "Sam",
age: 30,
gender: "male"
}, {
name: "Suzy",
age: 4,
gender: "female"
}]
for (var i = 0; i < peopleWhoWantToSeeMadMaxFuryRoad.length; i++) {
if (peopleWhoWantToSeeMadMaxFuryRoad[i].age < 18) {
console.log("person " + peopleWhoWantToSeeMadMaxFuryRoad[i].name + ' is under 18')
}
}
Or, to be more concise, use an array method and destructure:
var peopleWhoWantToSeeMadMaxFuryRoad = [{
name: "Mike",
age: 12,
gender: "male"
}, {
name: "Madeline",
age: 80,
gender: "female"
}, {
name: "Cheryl",
age: 22,
gender: "female"
}, {
name: "Sam",
age: 30,
gender: "male"
}, {
name: "Suzy",
age: 4,
gender: "female"
}]
peopleWhoWantToSeeMadMaxFuryRoad.forEach(({ name, age }) => {
if (age < 18) {
console.log("person " + name + ' is under 18');
}
});
If you want a new array containing each person object whose age is under 18, use .filter instead of .forEach:
const under18 = peopleWhoWantToSeeMadMaxFuryRoad.filter(({ age}) => age < 18);

Problem in your code is you're not accessing the values properly, j == 'number' && j < 18 here you're comparing with index instead of age
var data=[{name:"Mike",age:12,gender:"male"},{name:"Madeline",age:80,gender:"female"},{name:"Cheryl",age:22,gender:"female"},{name:"Sam",age:30,gender:"male"},{name:"Suzy",age:4,gender:"female"}]
data.forEach(e=> {
if(e.age >= 18 ) {
console.log( e.name + " you're 18+" )
} else {
console.log( e.name + " Below 18")
}
})

Using forEach
var peopleWhoWantToSeeMadMaxFuryRoad = [
{
name: "Mike",
age: 12,
gender: "male"
},{
name: "Madeline",
age: 80,
gender: "female"
},{
name: "Cheryl",
age: 22,
gender: "female"
},{
name: "Sam",
age: 30,
gender: "male"
},{
name: "Suzy",
age: 4,
gender: "female"
}
]
peopleWhoWantToSeeMadMaxFuryRoad.forEach((e)=>e.age<18?console.log(e.name + ' is underage'):true)

You could map a Boolean onto each person, filter by the Boolean, then iterate over the remaining array to log.
var peopleWhoWantToSeeMadMaxFuryRoad = [
{
name: "Mike",
age: 12,
gender: "male"
},{
name: "Madeline",
age: 80,
gender: "female"
},{
name: "Cheryl",
age: 22,
gender: "female"
},{
name: "Sam",
age: 30,
gender: "male"
},{
name: "Suzy",
age: 4,
gender: "female"
}
];
var under18 = peopleWhoWantToSeeMadMaxFuryRoad.map((peeps)={
peeps["under18"] = (peeps.age < 18);
return peeps;
}).filter((peeps)=>{
return peeps.uner18;
}).forEach((peeps)=>{
console.log(`${peeps.name} is under 18`);
})

Suggestion would be to use Array Filter to get rid of all 18 or over then loop the remaining and print the console.log.
const peopleWhoWantToSeeMadMaxFuryRoad = [..];
peopleWhoWantToSeeMadMaxFuryRoad.filter(person => person.age < 18)
.forEach(person => console.log(`${person.name} is under 18`));

Related

Why is my condition that checks diff between two arrays of objects wrong?

What is wrong in this if condition. I am getting the wrong result. I need to get equal values in these two objects and diff between them.
const firstArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 23, city: 'Berlin' }, { name: 'Sara', age: 28, city: 'Paris' }, { name: 'Rash', age: 20, city: 'Dubai' } ];
const secondArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 27, city: 'Berlin' }, { name: 'Hary', age: 29, city: 'London' }, ];
for (let i = 0; i < firstArr.length; i++) {
for (let j = 0; j < secondArr.length; j++) {
if (firstArr[i].name == secondArr[j].name) {
console.log('eq', firstArr[i].city, secondArr[j].city)
}
if (firstArr[i].name != secondArr[j].name) {
console.log('not found in second array', firstArr[i].city)
}
if (secondArr[j].name != firstArr[i].name) {
console.log('not found in first array', secondArr[j].city)
}
}
}
Currently you compare each element of the first array with each element of the second array. You could instead use Array.prototype.some and Array.prototype.every to filter the arrays and to find the intersection resp. difference. Then you can map the objects to the city names.
const firstArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 23, city: 'Berlin' }, { name: 'Sara', age: 28, city: 'Paris' }, { name: 'Rash', age: 20, city: 'Dubai' } ];
const secondArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 27, city: 'Berlin' }, { name: 'Hary', age: 29, city: 'London' }, ];
function intersect(lhs, rhs) {
return lhs.filter(el => rhs.some(el2 => el.name === el2.name)).map(el => el.city);
}
function diff(lhs, rhs) {
return lhs.filter(el => rhs.every(el2 => el.name !== el2.name)).map(el => el.city);
}
console.log(intersect(firstArr, secondArr));
console.log(diff(firstArr, secondArr));
console.log(diff(secondArr, firstArr));
I loop the first array first and find matches in second array. If there is a match, diff is displayed. If there is no such match, then the correct text is being displayed. An array is built along the way, which is used to simplify the loop on the second array.
const firstArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 23, city: 'Berlin' }, { name: 'Sara', age: 28, city: 'Paris' }, { name: 'Rash', age: 20, city: 'Dubai' } ];
const secondArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 27, city: 'Berlin' }, { name: 'Hary', age: 29, city: 'London' }, ];
let names = [];
for (let first of firstArr) {
let matches = secondArr.filter((second) => (first.name === second.name));
if (matches.length) {
console.log('eq', first.city, matches[0].city)
} else {
console.log('not found in second array', first.city);
}
names.push(first.name);
}
for (let second of secondArr) {
if (names.indexOf(second.name) === -1) console.log('not found in first array', second.city);
}
Try this:
const firstArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 23, city: 'Berlin' }, { name: 'Sara', age: 28, city: 'Paris' }, { name: 'Rash', age: 20, city: 'Dubai' } ];
const secondArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 27, city: 'Berlin' }, { name: 'Hary', age: 29, city: 'London' }, ];
var eq = [], uniqueInFirst = [], uniqueInSecond = [];
for (let i = 0; i < firstArr.length; i++) {
var secondArrCities = Object.values(secondArr).map ((obj) => {return obj.city})
if (secondArrCities.includes(firstArr[i].city)) {
eq.push(firstArr[i].city)
} else {
uniqueInFirst.push(firstArr[i].city)
}
}
for (let i = 0; i < secondArr.length; i++) {
var firstArrCities = Object.values(firstArr).map ((obj) => {return obj.city})
if (!firstArrCities.includes(secondArr[i].city)) {
uniqueInSecond.push(secondArr[i].city)
}
}
console.log(eq)
console.log(uniqueInFirst)
console.log(uniqueInSecond)

Array manipulating dynamically with an object using javascript

I have an array of object as below.
const data =
[
{id: 1, recordCreatedTime: '2020-05-08T10:57:35.000Z', name: 'Roy', age: 21, gender: 'Male'},
{id: 2, name: 'Paul', age: 24, gender: 'Male'},
{id: 3, recordCreatedTime: '2020-05-06T11:26:35.000Z', name: 'John', age: 21, gender: 'Male'},
{id: 4, recordCreatedTime: '2020-05-08T05:11:35.000Z', name: 'Peter', age: 26, gender: 'Female'}
]
I want to filter the above array with the contents by multiple filter dynamically from the object below. If i add a new element in the object below it should work fine. Also if some element miss in the array of object then also the logic should work fine.
const object= {recordCreatedTime: "05/08/2020", name: "Peter", gender: "al"}
For filtering with name it should use ===, for gender it should filter with includes and for filtering with recordCreatedTime it should filter with includes with MM/DD/YYYY format. Below is the code i'm using to achieve this, which is not working fine.
const result = data.filter(listObject =>
Object.entries(object).every(
([key, value]) =>
listObject[key] &&
(listObject[key] === Object.keys(object)[2]
? listObject[key] === value
: key === Object.keys(object)[0]
? moment(listObject[key])
.format('MM/DD/YYYY')
.toString()
.includes(value.toString())
: listObject[key]
.toString()
.toLowerCase()
.includes(value.toString().toLowerCase()))
)
)
Can anyone please correct me? The expected output is:
[{id: 4, recordCreatedTime: '2020-05-08T05:11:35.000Z', name: 'Peter', age: 26, gender: 'Female'}
]
const data = [
{id: 1, recordCreatedTime: '2020-05-08T10:57:35.000Z', name: 'Roy', age: 21, gender: 'Male'},
{id: 2, name: 'Paul', age: 24, gender: 'Male'},
{id: 3, recordCreatedTime: '2020-05-06T11:26:35.000Z', name: 'John', age: 21, gender: 'Male'},
{id: 4, recordCreatedTime: '2020-05-08T05:11:35.000Z', name: 'Peter', age: 26, gender: 'Female'}
];
const object = {recordCreatedTime: "05/08/2020", name: "Peter", gender: "al"};
const result = data.filter((listObject, i) => {
let x = false, y = false, z = false;
Object.entries(object).forEach(([key, value]) => {
if (key === 'recordCreatedTime') {
x = listObject[key] && ((new Date(listObject[key]).toLocaleDateString()) === new Date(value).toLocaleDateString());
} else if (key === 'gender') {
y = listObject[key] && (listObject[key].includes(value));
} else {
z = listObject[key] && (listObject[key] === value);
}
});
return x && y && z;
});
console.log(result);

Comparing the properties of objects of two arrays and storing it in a new array

I would like to compare a property of an object of two arrays of different lengths. If my condition is true (gender check) and then if that property matches then I would like to combine the properties of that object from both arrays and store it in a different array.
For example:
// array 1
var array1 = [{name: 'Jan', age: 19, category: {gender: 'Male'}}, {name: 'Suzy', age: 29, category: {gender: 'Female'}}, {name: 'Peter', age: 39, category: {gender: 'Male'}}, {name: 'Bart', age: 49, category: {gender: 'Male'}}, {name: 'John', age: 59, category: {gender: 'Male'}}];
// array 2
var array2 = [{name:'Kean', job: 'Technician'},{name:'Nick', job:'Mathematics'},{name: 'Jan', job: 'Tester'}, {name: 'Suzy', job:'Developer'}, {name: 'Peter', job: 'Scrum master'}]
Expected result:
var resultMale = [{name: 'Jan', age: 19,job: 'Tester'}, {name: 'Peter', age: 39, job: 'Scrum master'}];
var resultFemale = [{name: 'Suzy', age: 29, job:'Developer'}];
Below is my attempt just to show that I have been putting all my effort to find a solution myself. I have changed all the functions and variable names
this.
xxxxxxxx.getContractsForRules().then(res => {
// res.xxxxxx.forEach(function (obj) {
// if(obj.contract.product.xxxxxxx=== 'xxxxxxx') {
// console.log(this.xxxxxx.xx);
// for(let i=0; i < this.xxxxxxx.length; i++) {
// if(obj.contract.accountNumber === this.xxxxxxxx[i].ibanNumber) {
// this.currentAccount = {
// accountNumber: res.xxxxx[i].contract.accountNumber,
// accountName: res.xxxxx[i].contract.customer.xxxxxx
// };
// this.xxxxxxx.push(this.xxxxxx);
// }
// };
// }
// });
this.result = res.contractList.filter(item => this.allCurrentAccounts.);
if(res.xxxx[i].contract.xxxxx=== this.xxxxx[i].ibanNumber) {
this.savingAccount = {
accountNumber: xxxx.xxxx[i].contract.accountNumber,
accountName: res.xxxxx[i].contract.customer.xxxxx
};
this.xxxxx.push(this.xxxxx);
}
});
this.test();
}
What you finally need is an Intersection of both the arrays. So, you could do the following -
var array1 = [{ name: 'Jan', age: 19, category: { gender: 'Male' } }, { name: 'Suzy', age: 29, category: { gender: 'Female' } }, { name: 'Peter', age: 39, category: { gender: 'Male' } }, { name: 'Bart', age: 49, category: { gender: 'Male' } }, { name: 'John', age: 59, category: { gender: 'Male' } }];
var array2 = [{ name: 'Kean', job: 'Technician' }, { name: 'Nick', job: 'Mathematics' }, { name: 'Jan', job: 'Tester' }, { name: 'Suzy', job: 'Developer' }, { name: 'Peter', job: 'Scrum master' }];
// Empty arrays to contain final intersection array for both male & females
var resultMale = [], resultFemale = [];
/* now looping over both arrays to traverse all the elements from them */
// iterating over first array
array1.forEach(x => {
// iterating over second array
array2.forEach(y => {
// collect the objects only if the name attribute matches in both
if (x.name == y.name) {
// push into male array if gender is male else push into female array
if (x.category && x.category['gender'] == 'Male') {
resultMale.push({
name: x.name,
age: x.age,
job: y.job
});
} else if (x.category && x.category['gender'] == 'Female') {
resultFemale.push({
name: x.name,
age: x.age,
job: y.job
});
}
}
});
});
console.log(resultMale);
console.log(resultFemale);
Note - this can be optimized to reduce the time complexity.

How to get the index of an object in an array of objects when it matches completely javascript

I have an array of objects and I would like to get the index of the object in the array when I get a match.
I have the array as follows:
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
.....
];
Currently I am using indexOf which worked initially and now it doesn't work properly. It returns -1.
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = x.indexOf(find); // should return 1.
The whole should match in the array and should return the index of that object. How can I achieve this? Should I be using some() ?
Thank you
You can use .find instead of indexOf as 2 objects are never equal ( as they point to different reference in memory ) which is what you seem to pass as an argument.
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let found = x.find(function(item) {
// you can use the condition here
return item.info.id === 564;
});
console.log(found);
To find the index, you can use .findIndex method instead.
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let foundIndex = x.findIndex(function(item) {
// you can use the condition here
return item.info.id === 564;
});
console.log(foundIndex);
Objects cannot be compared by traditional equality in JavaScript. Instead, use the ES6 findIndex method to compare each object's properties with the desired values. Here is an example:
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = x.findIndex(element => element.info.id === find.info.id); // index === 1
The id value seems to be sufficient to identify an object in your scenario; if you need to compare more properties, you could obviously add additional equality checks (e.g., element.name === find.name) with the && operator.
If we live in the _.lodash world than this works since lodash would go deep on objects:
let data = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, age: 22, gender: "female"}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
];
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = _.findIndex(data, (i) => _.isEqual(i, find))
console.log(index) // 1
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
A more brutish approach which obviously it is not performant
and as pointed out wont work if the order of the props is different.
let data = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
];
var objectJSONs = data.map((i) => JSON.stringify(i))
let myJSON = JSON.stringify({name: "maggie", info: { id: 234, gender: "female", age: 22}});
let index = objectJSONs.indexOf(myJSON)
console.log(index) // 1
You can make use of underscore _.isEqual for Object comparison and some() or any looping mechanism to iterate the array.
let iFoundIndex = -1;
let bFound = x.some((data,index) => {
if(_.isEqual(data,find){
iFoundIndex = index;
return true;
}
return false;
}
//console.log(iFoundIndex);

Grouping by multiple fields per object

I am trying to determine the best data-type to sort an array of objects, into groups defined by properties. I have an array of objects, like so:
var people = [
{
name: 'Pete',
gender: 'Male',
age: 22
},
{
name: 'Samantha',
gender: 'Female',
age: 20
},
{
name: 'Frank',
gender: 'Male',
age: 22
},
{
name: 'Gary',
gender: 'Male',
age: 21
},
{
name: 'Maria',
gender: 'Female',
age: 20
},
{
name: 'Hannah',
gender: 'Female',
age: 21
},
{
name: 'Pete',
gender: 'Male',
age: 20
}
];
I need to group these objects into an arbitrary-defined group. E.g.:
Group 1: gender
Group 2: age
(This can be defined by the server and can change to contain a third group if we wish.)
Which then gives me (visually):
Male:
21:
Gary
22:
Pete
Frank
Female
20:
Samantha
Maria
21:
Hannah
I think the appropriate data type would be an object of objects. I.e.:
{
Male: {
21: {
[
{
name: 'Gary',
gender: 'Male',
age: 21
}
]
},
22: {
[
{
name: 'Pete',
gender: 'Male',
age: 22
},
{
name: 'Frank',
gender: 'Male',
age: 22
}
]
}
},
Female: {
20: {
[
{
name: 'Samantha',
gender: 'Female',
age: 20
},
{
name: 'Maria',
gender: 'Female',
age: 20
}
]
},
21: {
[
{
name: 'Hannah',
gender: 'Female',
age: 21
}
]
}
}
}
But I cannot work out, for the life of me, an appropriate algorithm to sort these objects into a data-type which represents the above.
There is a useful utility in underscore.js called _.groupBy(arr, callback) which I can use as follows:
_.groupBy(people, function (person) {
var props = ['gender', 'age'], // server-defined
prop = [];
for (var i = 0, length = props.length; i < length; i++) {
prop.push(person[props[i]]);
}
return prop.join('|');
});
This gives me a 1-depth object which I can use a for...in loop to iterate over the keys, and loop through to build the object above, but it's that bit of the code I'm stuck on.
The returned object would be:
{
"Male|22": [
{
"name": "Pete",
"gender": "Male",
"age": 22
},
{
"name": "Frank",
"gender": "Male",
"age": 22
}
],
"Female|20": [
{
"name": "Samantha",
"gender": "Female",
"age": 20
},
{
"name": "Maria",
"gender": "Female",
"age": 20
}
],
"Male|21": [
{
"name": "Gary",
"gender": "Male",
"age": 21
}
],
"Female|21": [
{
"name": "Hannah",
"gender": "Female",
"age": 21
}
],
"Male|20": [
{
"name": "Pete",
"gender": "Male",
"age": 20
}
]
}
I'm thinking of then looping through each key in the object, splitting at the pipe (|) and using recursion to construct a new object of objects containing the groups/array of data.
That's such a horrendous way of achieving this but I have no idea how to do it otherwise.
Is there a better way I'm missing?
Maybe this helps you. It utilises an array with the properties of the object and the result is grouped by the content of the properties.
The forEach loop iterates over the data. The reduce loop is for generating grouped properties for every given group and if it is the last one it returns an array, if not already there.
The last step is to push the value of one of people to the array.
var people = [{ name: 'Pete', gender: 'Male', age: 22 }, { name: 'Samantha', gender: 'Female', age: 20 }, { name: 'Frank', gender: 'Male', age: 22 }, { name: 'Gary', gender: 'Male', age: 21 }, { name: 'Maria', gender: 'Female', age: 20 }, { name: 'Hannah', gender: 'Female', age: 21 }, { name: 'Pete', gender: 'Male', age: 20 }],
groups = ['gender', 'age'],
grouped = {};
people.forEach(function (a) {
groups.reduce(function (o, g, i) { // take existing object,
o[a[g]] = o[a[g]] || (i + 1 === groups.length ? [] : {}); // or generate new obj, or
return o[a[g]]; // at last, then an array
}, grouped).push(a);
});
document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');
you can use lodash
groupBy(people, (item) => item.age + item.gender);
I realy don't understand why people always use frameworks for that kind of things.
Vanilla is faster and this is not too hard to code...
var people = [ { name: 'Pete', gender: 'Male', age: 22 }, { name: 'Samantha', gender: 'Female', age: 20 }, { name: 'Frank', gender: 'Male', age: 22 }, { name: 'Gary', gender: 'Male', age: 21 }, { name: 'Maria', gender: 'Female', age: 20 }, { name: 'Hannah', gender: 'Female', age: 21 }, { name: 'Pete', gender: 'Male', age: 20 }];
var grouped = {}; // final object
for (var i=0,len=people.length,p;i<len;i++) { // faster than .forEach
p = people[i];
if (grouped[p.gender] === undefined) // twice faster then hasOwnProperty
grouped[p.gender] = {};
if (grouped[p.gender][p.age] === undefined)
grouped[p.gender][p.age] = [];
grouped[p.gender][p.age].push(p); // your groupby is HERE xD
}
document.getElementById('grouped').innerHTML = JSON.stringify(grouped, null, 2)
<pre id="grouped"></pre>
I'm going to disagree with you about your expected output. I think you should just have an object with Male and Female array properties and use this code to populate the arrays:
var obj = people.reduce(function (p, c, i) {
p[c.gender].push(c);
return p;
}, { Male: [], Female: [] });
If you want to then filter those arrays you can write functions like this:
function getMaleByAge(obj, age) {
return obj.Male.filter(function (el) {
return el.age === age;
})
}
getMaleByAge(obj, 21); // { name: "Gary", gender: "Male", age: 21 }
DEMO
Using _.groupBy & _.map
var output = _.map(_.groupBy(people, 'gender'),function(obj, key){
var temp = {};
temp[key] = _.groupBy(obj, 'age')
return temp;
});
console.log(JSON.stringify(output, null,' '))
Will give following output
[{
"Male": {
"20": [
{
"name": "Pete",
"gender": "Male",
"age": 20
}
],
"21": [
{
"name": "Gary",
"gender": "Male",
"age": 21
}
],
"22": [
{
"name": "Pete",
"gender": "Male",
"age": 22
},
{
"name": "Frank",
"gender": "Male",
"age": 22
}
]
}
},
{
"Female": {
"20": [
{
"name": "Samantha",
"gender": "Female",
"age": 20
},
{
"name": "Maria",
"gender": "Female",
"age": 20
}
],
"21": [
{
"name": "Hannah",
"gender": "Female",
"age": 21
}
]
}
}
]

Categories

Resources