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' ] ] ]