我有这个样本数据集:
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()
以下代码无效
我尝试映射final_list(这是[id,[names]]的列表,以查看new_item
中是否存在smaller_list
的ID,然后添加{{1到new_item.first
(应该是名字列表)。
这是正确的做法吗?
smaller_list[1]
答案 0 :(得分:5)
在我的方法中,我使用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}
];
let result = list.reduce( (acc, item, index) => {
if(acc[item.id]){
acc[item.id][1].push(item.first);
} else {
acc[item.id] = [item.id, [item.first]];
}
return acc;
}, []);
console.log(Object.values(result));
答案 1 :(得分:3)
我的解决方案是先对您的列表进行映射,然后将具有相似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},
]
let temp = [], result = [];
list.map(entry => {
if(!temp[entry.id]) temp[entry.id] = [entry.first]
else temp[entry.id].push(entry.first)
})
temp.forEach((names, id) => {
result.push([id, names])
})
console.log(JSON.stringify(result))
编辑:我使用数组作为temp
,因为ID是整数并且为了方便使用forEach
环。如果密钥是其他东西,那么你将使用哈希表。
答案 2 :(得分:3)
首先尝试为名称创建ID地图,然后将其映射到最终数组,例如
Split: lista
li := Array new: 30.
aux := Array new: 30.
j := 0.
1 to: (lista size / 30) ceiling do: [ :i |
1 to: 30 do: [ :k | aux at: k put: (lista at: k + j) ].
j := j + 30.
li at: i put: aux ].
^ li

答案 3 :(得分:1)
你想用reduce来做,并且用一个reduce来做它会很好。这里有3种方式
详细,更多循环
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
}, [])
与tuples1相同,简洁
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' ] ] ]
答案 4 :(得分:0)
万一您也在寻找非reduce
解决方案。
这是一个。这有点长,但这是因为我试图将问题分解成几个部分。
我首先浏览list
并将元素分类到各自的Id
。
然后对于已排序对象中的每个id
。我首先通过首先实例化外部元素来再次遍历它。
id
键推入元素。first
属性并将其添加到嵌套元素中。result
数组中。对你而言,这并不是太复杂,但我怀疑通过IDE看到代码的运行会更容易。
var 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},
]
var result = [];
var keyById = {};
// Sort the list of items to be keyed by: Id => [ item, item ]
list.forEach(function(item) {
if (!keyById.hasOwnProperty(item.id)) {
keyById[item.id] = [];
}
keyById[item.id].push(item);
});
// Build the data structure
for (var id in keyById) {
var item = []; // The outer element
var nestedItem = []; // The nested element belonging to the outer
item.push(id);
keyById[id].forEach(function(element) {
nestedItem.push(element.first);
});
item.push(nestedItem);
result.push(item);
}
console.log(JSON.stringify(result, '', 2));

答案 5 :(得分:0)
list
进行迭代,并使用id
作为key
来构建一个对象value
的{{1}}个array
s first
名。list
(如果您打算覆盖它)。array
生成id
个,其下一个同级元素是与array
相关联的value
的{{1}}个id
如果维护原始push
,则将list
转换为array
(或新list
。
var 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},
],
o = {}, p;
list.forEach( ( v ) => {
if ( !o[ v.id ] ) {
o[ v.id ] = [];
}
o[ v.id ].push( v.first );
} );
list = []; // if overwriting
for ( p in o ) {
if ( o.hasOwnProperty( p ) ) {
list.push( [ parseInt( p ), o[ p ] ] );
}
}
console.log( JSON.stringify( list ).replace( /,/g, ", " ) );
已编辑以添加parseInt()
(在另一个答案中注意到),因为问题的示例预期输出确实将数字显示为整数,而不是字符串。
并将演示输出更改为stringify
ed JSON
(在其他答案中也注意到(更易于阅读))。
答案 6 :(得分:-2)
为此编写一个简单的循环可能最容易:
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]])
}