Disons que j'ai un tableau comme celui-ci:
var arr = [
{type:"orange", title:"First"},
{type:"orange", title:"Second"},
{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}
];
et je veux que cela soit divisé en tableaux qui ont des objets qui ont le même type donc:
[{type:"orange", title:"First"},
{type:"orange", title:"Second"}]
[{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}]
Mais je veux le faire de manière générique afin de ne pas avoir de déclaration if spécifiant orange ou banane
// not like this
for (prop in arr){
if (arr[prop] === "banana"){
//add to new array
}
}
Pensées? JQuery et Underscore sont les deux options à utiliser.
JQuery et Underscore sont les deux options à utiliser.
nderscore groupBy
fait exactement ce dont vous avez besoin.
_.groupBy(arr, "type")
C'est un travail facile pour Array.reduce(...)
:
function groupBy(arr, property) {
return arr.reduce(function(memo, x) {
if (!memo[x[property]]) { memo[x[property]] = []; }
memo[x[property]].Push(x);
return memo;
}, {});
}
var o = groupBy(arr, 'type'); // => {orange:[...], banana:[...]}
o.orange; // => [{"type":"orange","title":"First"},{"type":"orange","title":"Second"}]
o.banana; // => [{"type":"banana","title":"Third"},{"type":"banana","title":"Fourth"}]
Bien sûr, si votre ou vos navigateurs cibles ne prennent pas en charge ECMAScript 262 5e édition, vous devrez implémenter "réduire" par vous-même, ou utiliser une bibliothèque polyfill, ou choisir une autre réponse.
[Mise à jour] Voici une solution qui devrait fonctionner avec n'importe quelle version de JavaScript:
function groupBy2(xs, prop) {
var grouped = {};
for (var i=0; i<xs.length; i++) {
var p = xs[i][prop];
if (!grouped[p]) { grouped[p] = []; }
grouped[p].Push(xs[i]);
}
return grouped;
}
Cela suppose un tableau d'objets:
function groupBy(array, property) {
var hash = {};
for (var i = 0; i < array.length; i++) {
if (!hash[array[i][property]]) hash[array[i][property]] = [];
hash[array[i][property]].Push(array[i]);
}
return hash;
}
groupBy(arr,'type') // Object {orange: Array[2], banana: Array[2]}
groupBy(arr,'title') // Object {First: Array[1], Second: Array[1], Third: Array[1], Fourth: Array[1]}
Construisez simplement un dictionnaire qui contient les objets en fonction de leur titre. Vous pouvez le faire comme ceci:
js
var arr = [
{type:"orange", title:"First"},
{type:"orange", title:"Second"},
{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}
];
var sorted = {};
for( var i = 0, max = arr.length; i < max ; i++ ){
if( sorted[arr[i].type] == undefined ){
sorted[arr[i].type] = [];
}
sorted[arr[i].type].Push(arr[i]);
}
console.log(sorted["orange"]);
console.log(sorted["banana"]);
démo jsfiddle: http://jsfiddle.net/YJnM6/
Version TypeScript.
/**
* Group object array by property
* Example, groupBy(array, ( x: Props ) => x.id );
* @param array
* @param property
*/
export const groupBy = <T>(array: Array<T>, property: (x: T) => string): { [key: string]: Array<T> } =>
array.reduce((memo: { [key: string]: Array<T> }, x: T) => {
if (!memo[property(x)]) {
memo[property(x)] = [];
}
memo[property(x)].Push(x);
return memo;
}, {});
export default groupBy;