Tru*_*ran 102 javascript arrays grouping object lodash
有没有人知道(如果可能的话,还是lodash)通过对象键对对象数组进行分组,然后根据分组创建一个新的对象数组?例如,我有一个汽车对象数组:
var cars = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'make': 'kia',
'model': 'optima',
'year': '2012'
},
];
Run Code Online (Sandbox Code Playgroud)
我想制作一个新的汽车对象数组,按以下方式分组make:
var cars = {
'audi': [
{
'model': 'r8',
'year': '2012'
}, {
'model': 'rs5',
'year': '2013'
},
],
'ford': [
{
'model': 'mustang',
'year': '2012'
}, {
'model': 'fusion',
'year': '2015'
}
],
'kia': [
{
'model': 'optima',
'year': '2012'
}
]
}
Run Code Online (Sandbox Code Playgroud)
Nin*_*olz 206
在普通的Javascript中,您可以使用Array#reduce对象
var cars = [{ make: 'audi', model: 'r8', year: '2012' }, { make: 'audi', model: 'rs5', year: '2013' }, { make: 'ford', model: 'mustang', year: '2012' }, { make: 'ford', model: 'fusion', year: '2015' }, { make: 'kia', model: 'optima', year: '2012' }],
result = cars.reduce(function (r, a) {
r[a.make] = r[a.make] || [];
r[a.make].push(a);
return r;
}, Object.create(null));
console.log(result);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }Run Code Online (Sandbox Code Playgroud)
Jon*_*ice 65
蒂莫的答案是我会怎么做.很简单_.groupBy,并允许在分组结构中的对象中进行一些复制.
但是OP也要求删除重复的make密钥.如果你想一路走下去:
var grouped = _.mapValues(_.groupBy(cars, 'make'),
clist => clist.map(car => _.omit(car, 'make')));
console.log(grouped);
Run Code Online (Sandbox Code Playgroud)
产量:
{ audi:
[ { model: 'r8', year: '2012' },
{ model: 'rs5', year: '2013' } ],
ford:
[ { model: 'mustang', year: '2012' },
{ model: 'fusion', year: '2015' } ],
kia: [ { model: 'optima', year: '2012' } ] }
Run Code Online (Sandbox Code Playgroud)
如果您想使用Underscore.js执行此操作,请注意_.mapValues调用其版本_.mapObject.
Tim*_*imo 51
你在找_.groupBy().
如果需要,从对象中删除要分组的属性应该是微不足道的:
var cars = [{'make':'audi','model':'r8','year':'2012'},{'make':'audi','model':'rs5','year':'2013'},{'make':'ford','model':'mustang','year':'2012'},{'make':'ford','model':'fusion','year':'2015'},{'make':'kia','model':'optima','year':'2012'},];
var grouped = _.groupBy(cars, function(car) {
return car.make;
});
console.log(grouped);Run Code Online (Sandbox Code Playgroud)
<script src='https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js'></script>Run Code Online (Sandbox Code Playgroud)
作为奖励,您可以使用ES6箭头功能获得更好的语法:
const grouped = _.groupBy(cars, car => car.make);
Run Code Online (Sandbox Code Playgroud)
met*_*gfu 26
用于通过es6中的某个键对对象数组进行分组的简短版本:
result = array.reduce((h, obj) => Object.assign(h, { [obj.key]:( h[obj.key] || [] ).concat(obj) }), {})
Run Code Online (Sandbox Code Playgroud)
版本较长:
result = array.reduce(function(h, obj) {
h[obj.key] = (h[obj.key] || []).concat(obj);
return h;
}, {})
Run Code Online (Sandbox Code Playgroud)
似乎原始问题询问如何通过make对汽车进行分组,但省略了每个组中的make.所以答案看起来像这样:
result = cars.reduce((h, {model,year,make}) => {
return Object.assign(h, { [make]:( h[make] || [] ).concat({model,year})})
}, {})
Run Code Online (Sandbox Code Playgroud)
Jon*_*lms 14
它也可以通过一个简单的for循环:
const result = {};
for(const {make, model, year} of cars) {
if(!result[make]) result[make] = [];
result[make].push({ model, year });
}
Run Code Online (Sandbox Code Playgroud)
cdi*_*ins 12
这是您自己的groupBy函数,它是以下代码的一般化:https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore
function groupBy(xs, f) {
return xs.reduce((r, v, i, a, k = f(v)) => ((r[k] || (r[k] = [])).push(v), r), {});
}
const cars = [{ make: 'audi', model: 'r8', year: '2012' }, { make: 'audi', model: 'rs5', year: '2013' }, { make: 'ford', model: 'mustang', year: '2012' }, { make: 'ford', model: 'fusion', year: '2015' }, { make: 'kia', model: 'optima', year: '2012' }];
const result = groupBy(cars, (c) => c.make);
console.log(result);Run Code Online (Sandbox Code Playgroud)
Syn*_*Cap 11
我要离开REAL GROUP BY了JS数组例如完全相同的这个任务在这里
const inputArray = [
{ Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
{ Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" },
{ Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
{ Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" },
{ Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
{ Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" },
{ Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
{ Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
];
var outObject = inputArray.reduce(function(a, e) {
// GROUP BY estimated key (estKey), well, may be a just plain key
// a -- Accumulator result object
// e -- sequentally checked Element, the Element that is tested just at this itaration
// new grouping name may be calculated, but must be based on real value of real field
let estKey = (e['Phase']);
(a[estKey] ? a[estKey] : (a[estKey] = null || [])).push(e);
return a;
}, {});
console.log(outObject);Run Code Online (Sandbox Code Playgroud)
只需简单的 forEach 循环就可以在这里工作,无需任何库
var cars = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'make': 'kia',
'model': 'optima',
'year': '2012'
},
];
let ObjMap ={};
cars.forEach(element => {
var makeKey = element.make;
if(!ObjMap[makeKey]) {
ObjMap[makeKey] = [];
}
ObjMap[makeKey].push({
model: element.model,
year: element.year
});
});
console.log(ObjMap);Run Code Online (Sandbox Code Playgroud)
您可以尝试通过_.groupBy func修改每次迭代调用的函数内的对象.请注意,源数组会更改其元素!
var res = _.groupBy(cars,(car)=>{
const makeValue=car.make;
delete car.make;
return makeValue;
})
console.log(res);
console.log(cars);
Run Code Online (Sandbox Code Playgroud)
var cars = [{
make: 'audi',
model: 'r8',
year: '2012'
}, {
make: 'audi',
model: 'rs5',
year: '2013'
}, {
make: 'ford',
model: 'mustang',
year: '2012'
}, {
make: 'ford',
model: 'fusion',
year: '2015'
}, {
make: 'kia',
model: 'optima',
year: '2012'
}].reduce((r, a) => {
const {
model,
year,
make
} = a;
r[make] = [...r[make] || [], {
model,
year
}];
return r;
}, {});
console.log(cars);Run Code Online (Sandbox Code Playgroud)
创建一个可以重用的方法
Array.prototype.groupBy = function(prop) {
return this.reduce(function(groups, item) {
const val = item[prop]
groups[val] = groups[val] || []
groups[val].push(item)
return groups
}, {})
};
Run Code Online (Sandbox Code Playgroud)
然后在下面你可以按任何标准分组
const groupByMake = cars.groupBy('make');
console.log(groupByMake);
Run Code Online (Sandbox Code Playgroud)
Array.prototype.groupBy = function(prop) {
return this.reduce(function(groups, item) {
const val = item[prop]
groups[val] = groups[val] || []
groups[val].push(item)
return groups
}, {})
};
Run Code Online (Sandbox Code Playgroud)
添加提案Object.groupBy()并Map.groupBy()已达到第 4 阶段!
它已经在大多数主要浏览器上实现(请参阅caniuse),因此您可以执行以下操作:
const cars = [
{ make: 'audi', model: 'r8', year: '2012' },
{ make: 'audi', model: 'rs5', year: '2013' },
{ make: 'ford', model: 'mustang', year: '2012' },
{ make: 'ford', model: 'fusion', year: '2015' },
{ make: 'kia', model: 'optima', year: '2012' }
];
const grouped = Object.groupBy(cars, item => item.make);
console.log(grouped);Run Code Online (Sandbox Code Playgroud)
这将输出:
{
audi: [
{ make: 'audi', model: 'r8', year: '2012' },
{ make: 'audi', model: 'rs5', year: '2013' }
],
ford: [
{ make: 'ford', model: 'mustang', year: '2012' },
{ make: 'ford', model: 'fusion', year: '2015' }
],
kia: [
{ make: 'kia', model: 'optima', year: '2012' }
]
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用这个 core-js polyfill:
const cars = [
{ make: 'audi', model: 'r8', year: '2012' },
{ make: 'audi', model: 'rs5', year: '2013' },
{ make: 'ford', model: 'mustang', year: '2012' },
{ make: 'ford', model: 'fusion', year: '2015' },
{ make: 'kia', model: 'optima', year: '2012' }
];
const grouped = Object.groupBy(cars, item => item.make);
//console.log(grouped);
// Optional: remove the "make" property from resulting object
const entriesUpdated = Object
.entries(grouped)
.map(([key, value]) => [
key,
value.map(({make, ...rest}) => rest)
]);
const noMake = Object.fromEntries(entriesUpdated);
console.log(noMake);Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/core-js-bundle@3.31.1/minified.js"></script>Run Code Online (Sandbox Code Playgroud)
对于 key 可以为 null 并且我们希望将它们分组为其他的情况
var cars = [{'make':'audi','model':'r8','year':'2012'},{'make':'audi','model':'rs5','year':'2013'},{'make':'ford','model':'mustang','year':'2012'},{'make':'ford','model':'fusion','year':'2015'},{'make':'kia','model':'optima','year':'2012'},
{'make':'kia','model':'optima','year':'2033'},
{'make':null,'model':'zen','year':'2012'},
{'make':null,'model':'blue','year':'2017'},
];
result = cars.reduce(function (r, a) {
key = a.make || 'others';
r[key] = r[key] || [];
r[key].push(a);
return r;
}, Object.create(null));
Run Code Online (Sandbox Code Playgroud)
另一种解决方案:
var cars = [
{'make': 'audi','model': 'r8','year': '2012'}, {'make': 'audi','model': 'rs5','year': '2013'},
{'make': 'ford','model': 'mustang','year': '2012'}, {'make': 'ford','model': 'fusion','year': '2015'},
{'make': 'kia','model': 'optima','year': '2012'},
];
const reducedCars = cars.reduce((acc, { make, model, year }) => (
{
...acc,
[make]: acc[make] ? [ ...acc[make], { model, year }] : [ { model, year } ],
}
), {});
console.log(reducedCars);Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
152853 次 |
| 最近记录: |