J'ai un objet. Il ressemble à ci-dessous:
[
{
"name":"Display",
"group":"Technical detals",
"id":"60",
"value":"4"
},
{
"name":"Manufacturer",
"group":"Manufacturer",
"id":"58",
"value":"Apple"
},
{
"name":"OS",
"group":"Technical detals",
"id":"37",
"value":"Apple iOS"
}
]
Je voudrais regrouper ces données par champ de groupe et obtenir cet objet:
var obj = {
0 = [
{
'group' = 'Technical detals',
'name' = 'Display',
'id' = '60',
'value' = '4'
},
{
'group' = 'Technical detals',
'name' = 'OS',
'id' = '37',
'value' = 'Apple iOS'
}],
1 = [
{
'group' = 'Manufacturer',
'name' = 'Manufacturer',
'id' = '58',
'value' = 'Apple'
}]
}
Comment regrouper mon premier objet?
Essayez avec quelque chose comme ça:
function groupBy(collection, property) {
var i = 0, val, index,
values = [], result = [];
for (; i < collection.length; i++) {
val = collection[i][property];
index = values.indexOf(val);
if (index > -1)
result[index].Push(collection[i]);
else {
values.Push(val);
result.Push([collection[i]]);
}
}
return result;
}
var obj = groupBy(list, "group");
Garde en tête que Array.prototype.indexOf
n'est pas défini dans IE8 et les versions antérieures, mais il existe des polyfills communs pour cela.
Si vous utilisez underscore.js dans votre application, vous pouvez simplement faire ce qui suit:
var groups = _.groupBy(data, 'group'); // data is your initial collection
Ou si vous préférez ne pas utiliser de bibliothèque, vous pouvez le faire vous-même:
var groups = { };
data.forEach(function(item){
var list = groups[item.group];
if(list){
list.Push(item);
} else{
groups[item.group] = [item];
}
});
Vous pouvez voir les deux exemples en action http://jsfiddle.net/nkVu6/3/
Si vous aimez travailler avec ES6 Map
, alors c'est pour vous:
function groupBy(arr, prop) {
const map = new Map(Array.from(arr, obj => [obj[prop], []]));
arr.forEach(obj => map.get(obj[prop]).Push(obj));
return Array.from(map.values());
}
const data = [{ name: "Display", group: "Technical detals", id: 60, value: 4 }, { name: "Manufacturer", group: "Manufacturer", id: 58, value: "Apple" }, { name: "OS", group: "Technical detals", id: 37, value: "Apple iOS" }];
console.log(groupBy(data, "group"));
.as-console-wrapper { max-height: 100% !important; top: 0; }
L'instance Map
est créée à partir de paires clé/valeur générées à partir du tableau d'entrée. Les clés sont les valeurs de la propriété à regrouper et les valeurs sont initialisées sous forme de tableaux vides.
Ensuite, ces tableaux sont remplis. Enfin, les valeurs de la carte (c'est-à-dire les tableaux remplis) sont renvoyées.
Réduire est idéal pour des situations comme celle-ci. Étant donné list
ci-dessous, vos données d'entrée:
const list = [{
'name': 'Display',
'group': 'Technical detals',
'id': '60',
'value': '4'
},
{
'name': 'Manufacturer',
'group': 'Manufacturer',
'id': '58',
'value': 'Apple'
},
{
'name': 'OS',
'group': 'Technical detals',
'id': '37',
'value': 'Apple iOS'
}
];
const groups = list.reduce((groups, item) => {
const group = (groups[item.group] || []);
group.Push(item);
groups[item.group] = group;
return groups;
}, {});
console.log(groups);
Et si vous vouliez être immuable, vous pourriez écrire le reduce
comme ceci:
const list = [{
'name': 'Display',
'group': 'Technical detals',
'id': '60',
'value': '4'
},
{
'name': 'Manufacturer',
'group': 'Manufacturer',
'id': '58',
'value': 'Apple'
},
{
'name': 'OS',
'group': 'Technical detals',
'id': '37',
'value': 'Apple iOS'
}
];
const groups = list.reduce((groups, item) => ({
...groups,
[item.group]: [...(groups[item.group] || []), item]
}), {});
console.log(groups);
Selon que votre environnement autorise la syntaxe étendue.
Vous pouvez utiliser une table de hachage pour les groupes et Array#forEach
pour itérer le tableau.
Vérifiez ensuite si le hachage existe et sinon, affectez-lui un tableau vide et envoyez-le dans le jeu de résultats.
Plus tard Poussez l'élément réel dans le tableau du hachage.
function groupBy(array, group) {
var hash = Object.create(null),
result = [];
array.forEach(function (a) {
if (!hash[a[group]]) {
hash[a[group]] = [];
result.Push(hash[a[group]]);
}
hash[a[group]].Push(a);
});
return result;
}
var data = [{ name: "Display", group: "Technical detals", id: 60, value: 4 }, { name: "Manufacturer", group: "Manufacturer", id: 58, value: "Apple" }, { name: "OS", group: "Technical detals", id: 37, value: "Apple iOS" }];
console.log(groupBy(data, "group"));
.as-console-wrapper { max-height: 100% !important; top: 0; }
disons que votre tableau initial est affecté à data
data.reduce((acc, d) => {
if (Object.keys(acc).includes(d.group)) return acc;
acc[d.group] = data.filter(g => g.group === d.group);
return acc;
}, {})
cela vous donnera quelque chose comme
{
"Technical detals" = [
{
'group' = 'Technical detals',
'name' = 'Display',
'id' = '60',
'value' = '4'
},
{
'group' = 'Technical detals',
'name' = 'OS',
'id' = '37',
'value' = 'Apple iOS'
}],
"Manufacturer" = [
{
'group' = 'Manufacturer',
'name' = 'Manufacturer',
'id' = '58',
'value' = 'Apple'
}]
}
J'ai essayé d'utiliser la réponse marquée comme acceptée, mais j'ai remarqué qu'il manquait des éléments dans certains groupes, selon le type de bien évalué. C'est une solution dérivée de cette réponse:
function groupBy(collection, property) {
var i = 0, values = [], result = [];
for (i; i < collection.length; i++) {
if(values.indexOf(collection[i][property]) === -1) {
values.Push(collection[i][property]);
result.Push(collection.filter(function(v) { return v[property] === collection[i][property] }));
}
}
return result;
}
var obj = groupBy(list, "group");
Essayer
let g = (d,h={},r={},i=0)=>(d.map(x=>(y=x.group,h[y]?1:(h[y]=++i,r[h[y]-1]=[]),r[h[y]-1].Push(x))),r);
console.log( g(data) );
let data=[
{
"name":"Display",
"group":"Technical detals",
"id":"60",
"value":"4"
},
{
"name":"Manufacturer",
"group":"Manufacturer",
"id":"58",
"value":"Apple"
},
{
"name":"OS",
"group":"Technical detals",
"id":"37",
"value":"Apple iOS"
}
];
let g = (d,h={},r={},i=0)=>(d.map(x=>(y=x.group,h[y]?1:(h[y]=++i,r[h[y]-1]=[]),r[h[y]-1].Push(x))),r);
console.log(g(data));
Si vous utilisez lodash, vous pouvez utiliser groupBy
.
Il prend en charge à la fois le tableau et l'objet.
Exemple:
_.groupBy([6.1, 4.2, 6.3], Math.floor);
// => { '4': [4.2], '6': [6.1, 6.3] }
// The `_.property` iteratee shorthand.
_.groupBy(['one', 'two', 'three'], 'length');
// => { '3': ['one', 'two'], '5': ['three'] }