查找数组是否重复,然后选择它们

时间:2019-04-18 02:04:02

标签: javascript jquery arrays object ecmascript-6

我在主/父数组中有多个数组,如下所示:

var arr = [
    [1, 17],
    [1, 17],
    [1, 17],
    [2, 12],
    [5, 9],
    [2, 12],
    [6, 2],
    [2, 12],
    [2, 12]
];

我有代码选择重复3次或更多次(> 3次)的数组并将其分配给变量。

代码是:

var arr = [[1, 17], [1, 17], [1, 17], [2, 12], [5, 9], [2, 12], [6, 2], [2, 12]]
arr.sort((a, b) => a[0] - b[0] || a[1] - b[1])

// define equal for array
const equal = (arr1, arr2) => arr1.every((n, j) => n === arr2[j])

let GROUP_SIZE = 3
first = 0, last = 1, res = []

while(last < arr.length){
    if (equal(arr[first], arr[last])) last++
    else {
        if (last - first >= GROUP_SIZE)  res.push(arr[first])
        first = last
    }
}
if (last - first >= GROUP_SIZE)  res.push(arr[first])
console.log(res)

所以最终结果是:

console.log(repeatedArrays);
>>> [[1, 17], [2, 12]]

我的问题:但是问题是,我有一个像这样的数组{from: [12, 0], to: [14, 30]}

var arr = [
    [1, 17],
    [1, 17],
    [1, 17],
    [2, 12],
    [5, 9],
    [2, 12],
    [6, 2],
    {from: [12, 0], to: [14, 5]},
    {from: [12, 0], to: [14, 5]},
    {from: [4, 30], to: [8, 20]},
    {from: [12, 0], to: [14, 5]},
    {from: [4, 30], to: [8, 20]},
    [2, 12],
    [2, 12]
];

当我尝试使用上面的代码时,它不起作用。错误消息是:

  

未捕获的TypeError:arr1.every不是函数

最终结果应该为:

console.log(repeatedArrays);
>>> [[1, 17], [2, 12], {from: [12, 0], to: [14, 5]}]

如何使上面的代码起作用?

3 个答案:

答案 0 :(得分:1)

如果将非数组引入混合,则需要以不同的方式处理它。

您已经可以使用数组了,所以我要添加对象样式检查,以实现排序和相等。

var arr = [
  [1, 17],
  [1, 17],
  [1, 17],
  [2, 12],
  [5, 9],
  [2, 12],
  [6, 2],
  { from: [4, 30], to: [8, 21] },
  { from: [12, 0], to: [14, 5] },
  { from: [12, 0], to: [14, 5] },
  { from: [4, 30], to: [8, 20] },
  { from: [12, 0], to: [14, 5] },
  { from: [4, 30], to: [8, 20] },
  [2, 12],
  [2, 12]
];
arr.sort((a, b) => {
  if (a instanceof Array && b instanceof Array) {
    return a[0] - b[0] || a[1] - b[1]
  } else if (a instanceof Array || b instanceof Array) {
    return a instanceof Array ? -1 : 1
  } else {
    return a.from[0] - b.from[0] || a.from[1] - b.from[1] || a.to[0] - b.to[0] || a.to[1] - b.to[1]
  }
});

// define equal for array
const equal = (arr1, arr2) => {
  if (arr1 instanceof Array) {
    return arr1.every((n, j) => n === arr2[j]);
  } else {
    if (arr2 instanceof Array) return false;
    for (let k in arr1) {
      if (!arr1[k].every((n, j) => n === arr2[k][j])) {
        return false
      }
    }
    return true;
  }
};

let GROUP_SIZE = 3;
(first = 0), (last = 1), (res = []);

while (last < arr.length) {
  if (equal(arr[first], arr[last])) last++;
  else {
    if (last - first >= GROUP_SIZE) res.push(arr[first]);
    first = last;
  }
}
if (last - first >= GROUP_SIZE) res.push(arr[first]);
console.log(res);

答案 1 :(得分:0)

您可以使用函数reduce对对象进行分组和计数,然后执行函数filter以获取计数为>= 3的对象。

var array = [     [1, 17],     [1, 17],     [1, 17],     [2, 12],     [5, 9],     [2, 12],     [6, 2],     [2, 12],     [2, 12] ];

let result = Object.values(array.reduce((a, [c, b]) => {
  let key = `${c}|${b}`;
  (a[key] || (a[key] = {count: 0, value: [c, b]})).count++;
  return a;
}, {})).filter(o => {
  if (o.count >= 3) {
    delete o.count;
    return true;
  }
  
  return false;
}).map(({value}) => value);

console.log(result);
.as-console-wrapper { min-height: 100%; }

答案 2 :(得分:0)

非常简单-全部filter,然后使用Set和JSON方法删除重复项(因为它是嵌套数组而不是对象):

var array = [
    [1, 17],
    [1, 17],
    [1, 17],
    [2, 12],
    [5, 9],
    [2, 12],
    [6, 2],
    [2, 12],
    [2, 12]
];

var repeatedArrays = [...new Set(array.filter(e => array.filter(f => JSON.stringify(e.sort()) == JSON.stringify(f.sort()))).map(JSON.stringify))].map(JSON.parse);

console.log(repeatedArrays);