写一个函数" groupBy(array,callback)"

时间:2017-11-12 05:26:02

标签: javascript callback

我有一个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}]
  }

我对回调函数还很陌生,想要一些提示/建议就可以开始了。即使是指向优秀教程的链接也会非常感激。

非常感谢!

7 个答案:

答案 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)

&#13;
&#13;
    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;
&#13;
&#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));