我有一个JavaScript任务,我必须实现功能" groupBy" ,当给定一个对象数组和一个函数时, 返回一个对象,其中输入对象通过在每个对象上调用fn的结果来键入。
基本上,我必须编写一个函数," groupBy(array,callback)",返回一个返回以下内容的对象。
例如:
var list = [{id: "102", name: "Alice"},
{id: "205", name: "Bob", title: "Dr."},
{id: "592", name: "Clyde", age: 32}];
groupBy(list, function(i) { return i.id; });
Returns:
{
"102": [{id: "102", name: "Alice"}],
"205": [{id: "205", name: "Bob", title: "Dr."}],
"592": [{id: "592", name: "Clyde", age: 32}]
}
Example 2:
groupBy(list, function(i) { return i.name.length; });
Returns:
{
"3": [{id: "205", name: "Bob", title: "Dr."}],
"5": [{id: "102", name: "Alice"},
{id: "592", name: "Clyde", age: 32}]
}
我对回调函数还很陌生,想要一些提示/建议就可以开始了。即使是指向优秀教程的链接也会非常感激。
非常感谢!
答案 0 :(得分:4)
它是一个reduce()
单行。 Reduce允许您循环遍历数组并根据其回调的逻辑附加到新对象。在此函数中a
(用于累积)是我们正在制作的对象,而c
(对于当前项目)是循环中的每个项目一次一个。
这里特别简洁,因为传递对象键的函数是:
var list = [{id: "102", name: "Alice"},
{id: "205", name: "Bob", title: "Dr."},
{id: "592", name: "Clyde", age: 32}];
function groupBy(list, Fn) {
return list.reduce((a, c) => (a[Fn(c)] ? a[Fn(c)].push(c) : a[Fn(c)] = [c], a), {})
}
var t = groupBy(list, function(i) { return i.id; });
console.log(t)
var l = groupBy(list, function(i) { return i.name.length; });
console.log(l)

答案 1 :(得分:1)
使用纯JS解决方案:
var list = [{
id: "102",
name: "Alice"
},
{
id: "205",
name: "Bob",
title: "Dr."
},
{
id: "592",
name: "Clyde",
age: 32
}
];
function groupBy(array, callback) {
return array.reduce(function(store, item) {
var key = callback(item);
var value = store[key] || [];
store[key] = value.concat([item]);
return store;
}, {})
}
console.log('example 1: ', groupBy(list, function(i) { return i.id; }));
console.log('example 2: ', groupBy(list, function(i) { return i.name.length; }));

答案 2 :(得分:1)
下面是代码的链接:http://rextester.com/KROB29161
function groupBy(list, callback) {
// Declare a empty object
var obj = {};
// We then loop through the array
list.forEach(function(item) {
// We define the key of the object by calling the
// callback with the current item
var key = callback(item);
// If the field exists, add this item to it
if (obj[key]) {
obj[key] = obj[key].concat(item);
} else {
// If the field does not exist, create it and this value
// as an array
obj[key] = [item];
}
});
return obj;
}
答案 3 :(得分:0)
您可以使用Lodash _.groupBy
,它完全符合您的要求。 doc here
答案 4 :(得分:0)
var list = [{id: "102", name: "Alice"},
{id: "205", name: "Bob", title: "Dr."},
{id: "592", name: "Clyde", age: 32}];
console.log(groupBy(list, function(i) { return i.id; }));
console.log(groupBy(list, function(i) { return i.name.length; }));
以下是工作示例的链接:https://codepen.io/pablo-tavarez/pen/NwjrEZ?editors=0012
function groupBy(list, callback) {
var output = {};
var key
, i = 0;
// iterate over list of objects
for ( ; i < list.length; i++ ) {
// pass the current item to callback and get (current) key
key = callback(list[i]);
if (output[key]) {
// handle duplicate keys without overriding -- (optionally make all key value Arrays)
output[key] = [output[key]];
output[key].push(list[i]);
}
else {
output[key] = list[i];
}
}
return output;
}
答案 5 :(得分:0)
const Nodes = [];
for (let i = 0; i < 10; i++) {
Nodes.push({
radius: 5,
x: Math.random() * 500,
y: Math.random() * 500,
velocityX: Math.random(),
velocityY: Math.random()
});
}
collide() {
var quadtree = d3.quadtree().extent([
[
0, 0
],
[1500, 1000]
]).addAll(Nodes);
console.log(quadtree);
}
&#13;
答案 6 :(得分:0)
这里是使用reduce的另一种方法:
var list = [{
id: "102",
name: "Alice"
},
{
id: "205",
name: "Bob",
title: "Dr."
},
{
id: "592",
name: "Clyde",
age: 32
}
];
function groupBy(list, callback) {
return list.reduce((acc, x) => {
const key = callback(x);
if (!acc[key]) {
return {
...acc,
[key]: [x]
}
}
return {
...acc,
[key]: [...acc[key], x]
}
}, {})
}
// callback functions
function nameLength(obj) {
return obj.name.length;
}
function objectProperty(obj) {
return obj.id
}
console.log('group by name length:', groupBy(list, nameLength));
console.log('group by Id:', groupBy(list, objectProperty));