【问题标题】:Find if arrays repeat and then select them [closed]查找数组是否重复然后选择它们[关闭]
【发布时间】:2019-04-18 02:04:02
【问题描述】:

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

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]
];

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

未捕获的类型错误:arr1.every 不是函数

最终结果应该是:

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

我怎样才能使上面的代码工作?

【问题讨论】:

  • 您在寻找什么样的逻辑?您是否需要找到完整的 { from, to } 对象的 3 个副本才能将其包含在最终结果中,还是什么?
  • 你需要传入一个数组。 {from: [12, 0], to: [14, 5]} 是一个对象。
  • "...我有一个像这样的数组 {from: [12, 0], to: [14, 30]}" 该对象如何等同于:var array = [ [1, 17], [1, 17], [1, 17], [2, 12], [5, 9], [2, 12], [6, 2], {from: [12, 0], to: [14, 5]}, [2, 12], [2, 12] ];?以及为什么这个对象:{from: [12, 0], to: [14, 5]} 如此随意地塞进一个数组数组中?

标签: javascript jquery arrays object ecmascript-6


【解决方案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, 17], [2, 12], {from: [12, 0], to: [14, 5]}]
  • @baileyJchoi 我已经编辑了答案。令人惊讶的是,它在 Safari 和 Firefox 上运行不佳。它可以在 Node.js 和 Chrome 中运行。嗯……
  • 嗯,你知道为什么吗?
  • 似乎[2, 12] 没有被添加进去。我想知道为什么它会跳过它...
  • @baileyJchoi 两者都需要对数组进行排序,只是实现没有在 Safari 和 Firefox 上正确排序数组。它现在也适用于它们。
【解决方案2】:

您可以使用函数reduce 对对象进行分组和计数,然后执行函数filter 以获取计数为&gt;= 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%; }

【讨论】:

  • 我希望它输出[[1, 17], [2, 12], {from: [12, 0], to: [14, 5]}]
【解决方案3】:

真的很简单 - 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);

【讨论】:

  • 我希望它输出[[1, 17], [2, 12], {from: [12, 0], to: [14, 5]}]
猜你喜欢
  • 2019-04-26
  • 1970-01-01
  • 2013-05-20
  • 2015-03-04
  • 1970-01-01
  • 2020-10-28
  • 2018-01-24
  • 1970-01-01
  • 2015-09-19
相关资源
最近更新 更多