i have a array with objects in it. I need to create multiple arrays with objects grouped by one of the properties value. To clarify here is my array:
var people = [
new Person("Scott", "Guthrie", 38),
new Person("Scott", "Johns", 36),
new Person("Scott", "Hanselman", 39),
new Person("Jesse", "Liberty", 57),
new Person("Jon", "Skeet", 38)
];
I want to have one array with all the people with first name Scott, one with all with the first name Jesse and so on. Any suggestions will be helpful.
i have a array with objects in it. I need to create multiple arrays with objects grouped by one of the properties value. To clarify here is my array:
var people = [
new Person("Scott", "Guthrie", 38),
new Person("Scott", "Johns", 36),
new Person("Scott", "Hanselman", 39),
new Person("Jesse", "Liberty", 57),
new Person("Jon", "Skeet", 38)
];
I want to have one array with all the people with first name Scott, one with all with the first name Jesse and so on. Any suggestions will be helpful.
Share Improve this question edited Jan 16, 2016 at 9:44 T.J. Crowder 1.1m200 gold badges2k silver badges1.9k bronze badges asked Jan 16, 2016 at 9:31 user3377947user3377947 452 silver badges4 bronze badges 1-
1
Have a look at:
Array.prototype.filter()
orArray.prototype.reduce()
– Andreas Commented Jan 16, 2016 at 9:32
2 Answers
Reset to default 4To do that, you can loop through the array entries (in any of several ways, let's use forEach
here) and create an object or Map
keyed by the names you e across, with the value being the arrays of entries for those names.
Here's an example using an object:
// Create an object with no prototype, so it doesn't have "toString"
// or "valueOf", although those would be unlikely names for people to have
var nameArrays = Object.create(null);
// Loop the people array
people.forEach(function(person) {
// Get the name array for this person's name, if any
var nameArray = nameArrays[person.firstName];
if (!nameArray) {
// There wasn't one, create it
nameArray = nameArrays[person.firstName] = [];
}
// Add this entry
nameArray.push(person);
});
Live Example:
function Person(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
var people = [
new Person("Scott", "Guthrie", 38),
new Person("Scott", "Johns", 36),
new Person("Scott", "Hanselman", 39),
new Person("Jesse", "Liberty", 57),
new Person("Jon", "Skeet", 38)
];
// Create an object with no prototype, so it doesn't have "toString"
// or "valueOf", although those would be unlikely names for people to have
var nameArrays = Object.create(null);
// Loop the people array
people.forEach(function(person) {
// Get the name array for this person's name, if any
var nameArray = nameArrays[person.firstName];
if (!nameArray) {
// There wasn't one, create it
nameArray = nameArrays[person.firstName] = [];
}
// Add this entry
nameArray.push(person);
});
// Show results
Object.keys(nameArrays).sort().forEach(function(firstName) {
snippet.log(
"People named " + firstName +
": " +
nameArrays[firstName].map(function(person) {
return person.firstName + " " + person.lastName;
}).join(", ")
);
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange./a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
ES2015 adds Map
s to the language, so in an ES2015 environment we might use a Map
rather than an object for our nameArrays
:
// Creating the map:
let nameArrays = new Map();
// Getting an array:
nameArray = nameArrays.get(person.firstName);
// Adding an array:
nameArrays.set(person.firstName, []);
// Looping through the map:
for (let [firstName, nameArray] of nameArrays) {
// Use `firstName` and `nameArray` here
}
This is a more generic solution. getGroupedBy(persons, key)
returns an array of arrays with the grouped persons by the key.
function Person(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
var people = [
new Person("Scott", "Guthrie", 38),
new Person("Scott", "Johns", 36),
new Person("Scott", "Hanselman", 39),
new Person("Jesse", "Liberty", 57),
new Person("Jon", "Skeet", 38)
];
function getGroupedBy(persons, key) {
var groups = {}, result = [];
persons.forEach(function (a) {
if (!(a[key] in groups)) {
groups[a[key]] = [];
result.push(groups[a[key]]);
}
groups[a[key]].push(a);
});
return result;
}
document.write('<pre>' + JSON.stringify(getGroupedBy(people, 'firstName'), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(getGroupedBy(people, 'lastName'), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(getGroupedBy(people, 'age'), 0, 4) + '</pre>');