Javascript 在对象列表上使用.reduce()
我有以下示例数据集:Javascript 在对象列表上使用.reduce(),javascript,Javascript,我有以下示例数据集: let list = [ {'first': 'morgan', 'id': 1}, {'first': 'eric', 'id': 1}, {'first': 'brian', 'id': 2 }, {'first': 'derek', 'id' : 2}, {'first': 'courtney', 'id': 3}, {'first': 'eric', 'id': 4}, {'first': 'jon', 'id':4}, ] 我试图以这
let list = [
{'first': 'morgan', 'id': 1},
{'first': 'eric', 'id': 1},
{'first': 'brian', 'id': 2 },
{'first': 'derek', 'id' : 2},
{'first': 'courtney', 'id': 3},
{'first': 'eric', 'id': 4},
{'first': 'jon', 'id':4},
]
我试图以这样的方式结束:
[[1, [morgan, eric]], [2, [brian, derek]], [3, [courtney]], [4, [eric, jon]]
我正在使用.reduce()
函数映射列表。然而,我有点卡住了
我让这个工作:
let b = list.reduce((final_list, new_item) => {
x = final_list.concat([[new_item.id, [new_item.first]]])
return x
}, [])
但是,这会将列表展平为列表列表列表,但不会合并共享相似id的名称
我尝试使用.map()
下面的代码不起作用
我试图映射最终的_列表(这是一个[id,[名称]]列表),查看新_项目的id是否存在于较小的_列表中,然后添加新_项目。首先
到较小的_列表[1]
(应该是名称列表)
这是正确的方法吗
let b = list.reduce((final_list, new_item) => {
final_list.map((smaller_list) => {
if (smaller_list.indexOf((new_item.id)) >=0) {
smaller_list[1].concat(new_item.first)
// not sure what to do here...
} else {
// not sure what to do here either...
}
})
x = final_list.concat([[item.id, [item.first]]])
return x
}, [])
我的解决方案是首先映射您的列表,并将具有相似ID的列表组合起来,然后循环该结果,以便将格式更改为请求的格式
let list=[
{'first':'morgan','id':1},
{'first':'eric','id':1},
{'first':'brian','id':2},
{'first':'derek','id':2},
{'first':'courtney','id':3},
{'first':'eric','id':4},
{'first':'jon','id':4},
]
设温度=[],结果=[];
list.map(条目=>{
如果(!temp[entry.id])temp[entry.id]=[entry.first]
else temp[entry.id].push(entry.first)
})
临时forEach((名称、id)=>{
结果。推送([id,名称])
})
console.log(JSON.stringify(result))
为此编写普通循环可能是最简单的:
let final_list = []
for (k = 0; k < list.length; k += 2) {
let item1 = list[k]
let item2 = list[k + 1]
final_list.push([item1.id, [item1.first, item2.first]])
}
let final_list=[]
对于(k=0;k
首先尝试创建ID到名称的映射,然后将其映射到最终数组中,例如
let list=[
{'first':'morgan','id':1},
{'first':'eric','id':1},
{'first':'brian','id':2},
{'first':'derek','id':2},
{'first':'courtney','id':3},
{'first':'eric','id':4},
{'first':'jon','id':4},
]
const idMap=list.reduce((映射,项)=>{
if(Array.isArray(映射[item.id])){
映射[item.id]。推送(item.first)
}否则{
map[item.id]=[item.first]
}
返回图
}, {})
const b=Object.keys(idMap.map)(id=>[parseInt(id),idMap[id]]
console.info(JSON.stringify(b))
以防您也在寻找非reduce
解决方案
这里有一个。它有点冗长,但那是因为我试图将问题分解为几个部分
我首先浏览列表
,并将元素排序到各自的Id
然后,对于排序对象中的每个id
,我首先实例化一个外部元素,再次遍历它
首先将id
键推入元素
循环遍历所有关联的元素,提取它们的first
属性并将其添加到嵌套元素中
构建嵌套元素后,我只需将它们合并到父元素中,并将其附加到result
数组中
希望它对您来说不太复杂,但我怀疑通过IDE查看正在运行的代码会更容易
var列表=[
{'first':'morgan','id':1},
{'first':'eric','id':1},
{'first':'brian','id':2},
{'first':'derek','id':2},
{'first':'courtney','id':3},
{'first':'eric','id':4},
{'first':'jon','id':4},
]
var结果=[];
var keyById={};
//对要键入的项列表进行排序:Id=>[项,项]
列表.forEach(功能(项){
如果(!keyById.hasOwnProperty(item.id)){
keyById[item.id]=[];
}
keyById[item.id]。推送(item);
});
//构建数据结构
for(keyById中的变量id){
var item=[];//外部元素
var nestedItem=[];//属于外部
项目推送(id);
keyById[id].forEach(函数(元素){
nestedItem.push(元素优先);
});
项目推送(nestedItem);
结果:推送(项目);
}
console.log(JSON.stringify(result',2));
在我的方法中,我使用reduce创建一个稀疏数组,索引作为列表id。然后我使用Object.values
将其压缩
let list=[
{'first':'morgan','id':1},
{'first':'eric','id':1},
{'first':'brian','id':2},
{'first':'derek','id':2},
{'first':'courtney','id':3},
{'first':'eric','id':4},
{'first':'jon','id':4}
];
让结果=列表。减少((附件、项目、索引)=>{
如果(根据[项目id]){
acc[item.id][1]。推送(item.first);
}否则{
acc[item.id]=[item.id[item.first]];
}
返回acc;
}, []);
console.log(Object.values(result));
不是很性感,但它可以工作
- 迭代
列表
并使用id
s作为键
s和数组
s的值
s构建一个对象
- 空的
列表
(如果您计划覆盖它)
- 遍历为每个
id
生成array
的结果对象,其下一个同级元素是与该id
关联的值中的名称的数组
,并将它们推入列表
(如果保留原始的列表
,则使用新的数组
)
var列表=[
{'first':'morgan','id':1},
{'first':'eric','id':1},
{'first':'brian','id':2},
{'first':'derek','id':2},
{'first':'courtney','id':3},
{'first':'eric','id':4},
{'first':'jon','id':4},
],
o={},p;
列表.forEach((v)=>{
如果(!o[v.id]){
o[v.id]=[];
}
o[v.id]。推送(v.first);
} );
列表=[];//如果覆盖
对于(o中的p){
如果(o.hasOwnProperty(p)){
push([parseInt(p),o[p]]);
}
}
log(JSON.stringify(list).replace(/,/g,,”);const tuples1 = list.reduce( (tuples, obj) => {
if( tuples.some( ( [id, _] ) => id === obj.id ) ){
tuples.find( ( [id, _] ) => id === obj.id )[1].push(obj.first)
}else{
tuples.push([obj.id, [obj.first]])
}
return tuples
}, [])
const tuples2 = list.reduce( (tuples, obj) =>
( tuples.some( ( [id, _] ) => id === obj.id ) ) ?
( tuples.find( ( [id, _] ) => id === obj.id )[1].push(obj.first), tuples ) :
( tuples.push([obj.id, [obj.first]]), tuples ), [])
const tuples3 = list.reduce( (tuples, obj) => {
const existingId = tuples.find( ( [id, _] ) => id === obj.id )
if( existingId ){
existingId[1].push(obj.first)
}else{
tuples.push([obj.id, [obj.first]])
}
return tuples
}, [])
[ [ 1, [ 'morgan', 'eric' ] ],
[ 2, [ 'brian', 'derek' ] ],
[ 3, [ 'courtney' ] ],
[ 4, [ 'eric', 'jon' ] ] ]