如何计算无突变数组中某个值的出现次数

时间:2018-08-20 21:27:13

标签: javascript arrays sorting functional-programming

我目前有一个数组数组,其中包含的零件都具有相同的序列号。我想做的是仅过滤出具有相同序列号和相同零件号的零件。我目前能够获得所有唯一零件号的列表,但是我一生都无法找出如何仅取出具有相同零件号和相同序列号的物品的方法。数组是按序列号排序的,所以

dupes = [
[{ sn: 001, partNum: 2505}]
[{ sn: 001, partNum: 9999}]
[{ sn: 001, partNum: 9999}],
[{ sn: 002, partNum: 1234}]
[{ sn: 002, partNum: 1234}],
[{ sn: 003, partNum: 555}]
[{ sn: 003, partNum: 8675}]]

我想要得到的是一个仅包含重复项的数组

[{ sn: 001, partNum: 9999}]
[{ sn: 001, partNum: 9999}],
[{ sn: 002, partNum: 1234}]
[{ sn: 002, partNum: 1234}]

我整天都在努力应对,还没有找到不使用突变的好的解决方案。如果零件号出现两次,是否可以过滤掉“ SN”?我还必须检查每个零件号,因为在某些情况下,我看到相同的序列号两次用于两个不同的零件号,如果这样做的话。 任何帮助都是很棒的...严重地卡在这里。

编辑:

我最终以另一种方式完成了这项任务。但是,我确实找到了一个很好的函数,可以让您计算数组中某个项目的所有出现次数。

function count(arr) {
  return arr.reduce((prev, curr) => (prev[curr] = ++prev[curr] || 1, prev), {})
}

我在这里https://code.i-harness.com/en/q/567c30

找到了它

2 个答案:

答案 0 :(得分:1)

如果需要,所有重复项:

var dupes = [
[{ sn: 001, partNum: 2505}],
[{ sn: 001, partNum: 9999}],
[{ sn: 001, partNum: 9999}],
[{ sn: 002, partNum: 1234}],
[{ sn: 002, partNum: 1234}],
[{ sn: 003, partNum: 555}],
[{ sn: 003, partNum: 8675}]]

var result = [];
for(i =1; i<dupes.length; i++) {
  if(dupes[i-1][0].sn == dupes[i][0].sn ) {
    if(dupes[i-1][0].partNum == dupes[i][0].partNum ) {
      result.push(dupes[i-1]);
      result.push(dupes[i]);
    }
  }
}
console.log(result);

无突变:您可以在函数内部声明结果数组,并且由于您没有更改重复对象,因此该函数将是纯函数。

var dupes = [
[{ sn: 001, partNum: 2505}],
[{ sn: 001, partNum: 9999}],
[{ sn: 001, partNum: 9999}],
[{ sn: 002, partNum: 1234}],
[{ sn: 002, partNum: 1234}],
[{ sn: 003, partNum: 555}],
[{ sn: 003, partNum: 8675}]]


function onlyDuplicates(dupes) {
  var result = [];
  for(i =1; i<dupes.length; i++) {
    if(dupes[i-1][0].sn == dupes[i][0].sn ) {
      if(dupes[i-1][0].partNum == dupes[i][0].partNum ) {
        result.push(dupes[i-1]);
        result.push(dupes[i]);
      }
    }
  }
  return result;
}

console.log(onlyDuplicates(dupes));

答案 1 :(得分:1)

McRist的解决方案存在很多问题。例如,如果彼此不相邻,则不会找到重复项:

var dupes = [ [ { sn: 001, partNum: 2505 } ]
            , [ { sn: 001, partNum: 9999 } ] // element 1
            , [ { sn: 002, partNum: 1234 } ] // element 2
            , [ { sn: 001, partNum: 9999 } ] // duplicate of element 1
            , [ { sn: 002, partNum: 1234 } ] // duplicate of element 2
            , [ { sn: 003, partNum: 555  } ]
            , [ { sn: 003, partNum: 8675 } ]
            ];

var result = [];

for (var i = 0, j = 1; j < dupes.length; i++, j++) {
    if (dupes[i][0].sn      === dupes[j][0].sn &&
        dupes[i][0].partNum === dupes[j][0].partNum) {
        result.push(dupes[i]);
        result.push(dupes[j]);
    }
}

// empty array, even though there are duplicates
console.log(JSON.stringify(result));

更糟糕的是,如果有两个以上的连续重复项,那么它将返回额外的元素:

var dupes = [ [ { sn: 001, partNum: 2505 } ]
            , [ { sn: 001, partNum: 9999 } ] // element 1
            , [ { sn: 001, partNum: 9999 } ] // duplicate of element 1
            , [ { sn: 001, partNum: 9999 } ] // duplicate of element 1
            , [ { sn: 003, partNum: 555  } ]
            , [ { sn: 003, partNum: 8675 } ]
            ];

var result = [];

for (var i = 0, j = 1; j < dupes.length; i++, j++) {
    if (dupes[i][0].sn      === dupes[j][0].sn &&
        dupes[i][0].partNum === dupes[j][0].partNum) {
        result.push(dupes[i]);
        result.push(dupes[j]);
    }
}

// four elements, even though there are only three duplicates
console.log(JSON.stringify(result));

这是一个只返回那些重复的元素的解决方案。此外,它不使用任何形式的突变:

var dupes = [ [ { sn: 001, partNum: 2505 } ]
            , [ { sn: 001, partNum: 9999 } ] // element 1
            , [ { sn: 002, partNum: 1234 } ] // element 2
            , [ { sn: 002, partNum: 1234 } ] // duplicate of element 2
            , [ { sn: 002, partNum: 1234 } ] // duplicate of element 2
            , [ { sn: 001, partNum: 9999 } ] // duplicate of element 1
            , [ { sn: 003, partNum: 555  } ]
            , [ { sn: 003, partNum: 8675 } ]
            ];

const duplicates = (xs, eq) =>
    xs.filter((x, i) =>      // filter those elements
        xs.some((y, j) =>    // for which there's another element
            i !== j &&       // which is not the same and
            eq(x, y)));      // is a duplicate

const eq = ([x], [y]) =>     // two elements are the same if
    x.sn      === y.sn &&    // they have the same serial number and
    x.partNum === y.partNum; // the same part number

// correctly returns all five duplicates
console.log(JSON.stringify(duplicates(dupes, eq)));

希望有帮助。