如何循环并推动 reduce 函数的累加器?

How to loop and push on the accumulator of a reduce function?

我正在尝试减少一个数组,并将其转换为多个数组。

  const array = [
    { a: 1, b: 6 },
    { a: 1, b: 5 },
    { a: 1, b: 6 },
    { a: 1, b: 4 },
    { a: 1, b: 5 }
  ];

  var newArray = array.reduce(
    (memo, curr) => {
      memo.forEach((item, key) => {
        const found = item.filter((el) => el.a === curr.a && el.b === curr.b);
        if (found.length > 0) return memo[key].push(curr);
        else return memo.push([curr]);
      });

      return memo;
    },
    [[]]
  );

我想要得到的结果是

 [
    [
      { a: 1, b: 5 },
      { a: 1, b: 5 }
    ],
    [
      { a: 1, b: 6 },
      { a: 1, b: 6 },
    ],
    [
      { a: 1, b: 4 },
    ]
 ];

但正如您尝试所见,因为我按下备忘录,循环继续触发。结果包含数百个数组。

我应该如何限制此循环并获得正确的结果?

提前致谢:)

你可以使用Map将元素按{a, b}的键分组,然后得到分组的值

const array = [
  { a: 1, b: 6 },
  { a: 1, b: 5 },
  { a: 1, b: 6 },
  { a: 1, b: 4 },
  { a: 1, b: 5 },
];

var newArray = Array.from(
  array
    .reduce((map, curr) => {
      const key = JSON.stringify({ a: curr.a, b: curr.b });

      if (!map.has(key)) {
        map.set(key, []);
      }

      map.get(key).push(curr);

      return map;
    }, new Map())
    .values()
);

console.log(newArray);

如果你在 for 循环中推送,它也会在每次 reduce 函数迭代时推送。

你可以通过像这里这样添加一些局部变量来实现

const array = [
    { a: 1, b: 6 },
    { a: 1, b: 5 },
    { a: 1, b: 6 },
    { a: 1, b: 4 },
    { a: 1, b: 5 }
  ];
  
  // shift changes the orginal array
    // it will remove and return firstElement
  var firstElement = array.shift(1);


  var newArray = array.reduce(
    (memo, curr) => {
    let isFound = false;
    let index = 0;
      memo.forEach((item, key) => {
        const found = item.filter((el) => el.a === curr.a && el.b === curr.b);
        if(found.length > 0){
             index = key;
           isFound = true;
           return;
        }
       
      });
      if(isFound) {
        memo[index].push(curr);
      } else {
         memo.push([curr]);
      }
      return memo;
    },
    [[firstElement]]
  );
  
  console.log(newArray);

看看你的代码。你有一个三重嵌套循环,这是疯狂的,绝对不需要实现这个。为什么不使用地图?

这是一个函数,可以对给定的任何对象数组执行您想执行的操作。

const array = [
    { a: 1, b: 6 },
    { a: 1, b: 5 },
    { a: 1, b: 6 },
    { a: 1, b: 4 },
    { a: 1, b: 5 },
];

const separate = (arr) => {
    const reduced = arr.reduce((acc, curr) => {
        const path = JSON.stringify(curr);

        if (!acc[path]) acc[path] = [];

        acc[path].push(curr);

        return acc;
    }, {});

    return Object.values(reduced);
};

console.log(separate(array));