现在我拉了几个小时,所以有时间从SO那里寻求帮助
我有一个对象数组,像这样:
const data = [
{city: "London", surname: "jones"},
{city: "Manchester", surname: "jones"},
{city: "Leeds", surname: "smith"},
{city: "Birmingham", surname: "smith"},
{city: "Rhyl", surname: "clarkson"},
{city: "Blackpool", surname: "walker"},
{city: "Rhyl", surname: "walker"},
{city: "Blackpool", surname: "fletcher"}
];
// Actual data is much more complex, this is just a simplified example
我基本上是尝试根据字段(在此示例surname
中)对数据进行分组。姓氏值事先未知,因此需要动态。因此,您将查看数组中的下一项,如果它与分组的前一项匹配,则但是如果不匹配,则它将开始一个新的组。
最终结果看起来像这样:
const outcome = {
jones: [...2 objects],
smith: [...2 objects],
clarkson: [...1 objects],
walker: [...2 objects],
fletcher: [...1 objects]
}
我最初的想法是,我需要遍历每个项目并将其与下一个项目进行比较,因此最初着眼于reduce但无法正确实现,因此我开始遍历data
数组中的项目,然后将其与下一个进行比较(通过从map
获取索引并对其进行递增以查看下一个项目,但这确实很麻烦。
algo和CS并不是我的强项,但我觉得我做这件事的方式很脏,而且已经有一种模式,因为它必须是一项常见任务
我的下一个方法是遍历每个添加项,向数据中添加一些内容,例如grouping
id,即group: 1
,保持增量,++
仅在{{ 1}}与前一个不匹配,但是作为id听起来仍然不是“最优”,因此必须在每个组上运行surname
才能以正确的格式获取数据。
N.B。我已经看到了几个与我的问题相关的SO问题,但它们错过了必须按动态值排序的重要因素,如果知道这些值,这是一件容易的事
任何指导将不胜感激
谢谢
答案 0 :(得分:2)
有很多方法可以做到这一点。我想到的reduce
是最好的。
请参见以下代码段:
const data = [
{city: "London", surname: "jones"},
{city: "Manchester", surname: "jones"},
{city: "Leeds", surname: "smith"},
{city: "Birmingham", surname: "smith"},
{city: "Rhyl", surname: "clarkson"},
{city: "Blackpool", surname: "walker"},
{city: "Rhyl", surname: "walker"},
{city: "Blackpool", surname: "fletcher"}
];
function group(array,field){
return array.reduce((acc,elem)=>{
//whether the field value exist
if(acc[elem[field]]){
//if the field value exist, push elem to it:
acc[elem[field]].push(elem)
}else{
//if the field value doesn't exist, create an array with elem:
acc[elem[field]]=[elem]
}
//return accumulator for later use
return acc
},{})
}
const outcome = group(data,"surname")
console.log(outcome)
答案 1 :(得分:1)
您可以使用lodash中的groupBy
import { groupBy } from 'lodash'
const result = groupBy(data, item => item.surname)
结果将是:
{ jones:
[ { city: 'London', surname: 'jones' },
{ city: 'Manchester', surname: 'jones' } ],
smith:
[ { city: 'Leeds', surname: 'smith' },
{ city: 'Birmingham', surname: 'smith' } ],
clarkson: [ { city: 'Rhyl', surname: 'clarkson' } ],
walker:
[ { city: 'Blackpool', surname: 'walker' },
{ city: 'Rhyl', surname: 'walker' } ],
fletcher: [ { city: 'Blackpool', surname: 'fletcher' } ] }
答案 2 :(得分:1)
使用唯一键列表(使用Set
进行重复数据删除),reduce
,map
和filter
的组合可以有效:
const data = [
{city: "London", surname: "jones"},
{city: "Manchester", surname: "jones"},
{city: "Leeds", surname: "smith"},
{city: "Birmingham", surname: "smith"},
{city: "Rhyl", surname: "clarkson"},
{city: "Blackpool", surname: "walker"},
{city: "Rhyl", surname: "walker"},
{city: "Blackpool", surname: "fletcher"}
];
const result = [...new Set(data.map(x => x.surname))]
.reduce((acc, val) => {
return {...acc, [val]: [...(data
.filter(x => x.surname === val)
.map(x => { return { city: x.city } }))]};
}, {});
console.log(result);
答案 3 :(得分:0)
您要如何处理姓氏不连续的人。例如:琼斯,琼斯,史密斯,琼斯?
如果您想将它们全部分组,reduce本质上就是为此用例而设计的,它的使用非常简单:
const data = [
{city: "London", surname: "jones"},
{city: "Manchester", surname: "jones"},
{city: "Leeds", surname: "smith"},
{city: "Birmingham", surname: "smith"},
{city: "Rhyl", surname: "clarkson"},
{city: "Blackpool", surname: "walker"},
{city: "Rhyl", surname: "walker"},
{city: "Blackpool", surname: "fletcher"}
];
let grouped = data.reduce((acc, d) => {
acc[d.surname] = acc[d.surname] || [];
acc[d.surname].push(d.city);
return acc;
}, {});
console.log(grouped);
如果您想覆盖以前相同姓氏的序列(例如jones, jones, smith, jones
将映射到1个史密斯和1个(最后一个)琼斯),那么您还可以跟踪迭代的前一个人并进行比较姓:
const data = [
{city: "London", surname: "jones"},
{city: "Manchester", surname: "jones"},
{city: "Leeds", surname: "smith"},
{city: "Birmingham", surname: "smith"},
{city: "Rhyl", surname: "clarkson"},
{city: "Blackpool", surname: "walker"},
{city: "Rhyl", surname: "walker"},
{city: "Blackpool", surname: "fletcher"},
{city: "non-continuous jones", surname: "jones"},
];
let grouped = data.reduce(([acc, prevSurname], d) => {
if (prevSurname !== d.surname)
acc[d.surname] = [];
acc[d.surname].push(d.city);
return [acc, d.surname];
}, [{}])[0];
console.log(grouped);
答案 4 :(得分:0)
要达到预期效果,请根据姓氏键使用减少和添加对象
const data = [
{city: "London", surname: "jones"},
{city: "Manchester", surname: "jones"},
{city: "Leeds", surname: "smith"},
{city: "Birmingham", surname: "smith"},
{city: "Rhyl", surname: "clarkson"},
{city: "Blackpool", surname: "walker"},
{city: "Rhyl", surname: "walker"},
{city: "Blackpool", surname: "fletcher"}
];
console.log(data.reduce((acc,v)=> {
acc[v.surname]? (acc[v.surname].push(v)) : (acc[v.surname] =[v])
return acc
}, {}))