查找两个数组是否在数组中重复,然后选择它们

时间:2018-11-23 20:59:47

标签: javascript jquery arrays object multidimensional-array

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

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

以下是用于简化阅读的数组:

[1, 17]
[1, 17]
[1, 17]
[2, 12]
[5, 9]
[2, 12]
[6, 2]
[2, 12]
[2, 12]

我想选择重复3次或更多次(> 3)的数组并将其分配给变量。因此,在此示例中,var repeatedArrays将是[1, 17][2, 12]

所以这应该是最终结果:

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

我发现了类似的here,但它使用了underscore.js和lodash。

如何使用javascript甚至jquery(如果需要)呢?

6 个答案:

答案 0 :(得分:9)

您可以使用Map带有字符串化数组和计数,然后按计数过滤并恢复数组。

var array = [[1, 17], [1, 17], [1, 17], [2, 12], [5, 9], [2, 12], [6, 2], [2, 12]],
    result = Array
        .from(array.reduce(
            (map, array) =>
                (json => map.set(json, (map.get(json) || 0) + 1))
                (JSON.stringify(array)),
            new Map
         ))
        .filter(([, count]) => count > 2)
        .map(([json]) => JSON.parse(json));
        
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

使用所需数量的地图进行过滤。

var array = [[1, 17], [1, 17], [1, 17], [2, 12], [5, 9], [2, 12], [6, 2], [2, 12]],
    result = array.filter(
        (map => a => 
            (json =>
                (count => map.set(json, count) && !(2 - count))
                (1 + map.get(json) || 1)
            )
            (JSON.stringify(a))
        )
        (new Map)
    );
        
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

唯一!

var array = [[1, 17], [1, 17], [1, 17], [2, 12], [5, 9], [2, 12], [6, 2], [2, 12]],
    result = array.filter(
        (s => a => (j => !s.has(j) && s.add(j))(JSON.stringify(a)))
        (new Set)
    );
        
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:7)

尝试一下

array.filter(( r={}, a=>!(2-(r[a]=++r[a]|0)) ))

时间复杂度 O(n)(一个数组通过过滤器函数传递)。受Nitish答案的启发。

说明

(r={}, a=>...)将返回逗号后的最后一个表达式(即a=>...)(例如(5,6)==6)。在r={}中,我们只设置了一个临时对象,用于存储唯一键。在a=>...中的过滤器功能a中,我们有当前的array元素。在r[a]中,JS将a隐式转换为字符串(例如1,17)。然后在!(2-(r[a]=++r[a]|0))中,我们增加出现元素a的计数器,如果元素a出现3次,则返回true(作为过滤器功能值)。如果未定义r[a],则++r[a]返回NaN,然后返回NaN|0=0(也返回number|0=number)。 r[a]=会初始化第一个计数器值,如果我们省略它,++只会将NaN设置为r[a],这是不可递增的(因此我们需要在初始化时置零) 。如果我们删除2-作为结果,我们将获得没有重复的输入数组-或者,我们也可以通过a=>!(r[a]=a in r)来获取它。如果将2-更改为1-,我们将得到仅包含重复项的数组.

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

var r= array.filter(( r={}, a=>!(2-(r[a]=++r[a]|0)) ))

console.log(JSON.stringify(r));

答案 2 :(得分:5)

您可以像下面这样使用Object.reduceObject.entries

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


let res = Object.entries(
            array.reduce((o, d) => {
              let key = d.join('-')
              o[key] = (o[key] || 0) + 1

              return o
          }, {}))
          .flatMap(([k, v]) => v > 2 ? [k.split('-').map(Number)] : [])
  
  
console.log(res)

OR可能仅与Array.filters

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

let temp = {}
let res = array.filter(d => {
  let key = d.join('-')
  temp[key] = (temp[key] || 0) + 1
  
  return temp[key] == 3
})

console.log(res)

答案 3 :(得分:4)

换一种说法,您可以先对列表进行排序,然后循环浏览一次,然后取出满足您要求的元素。这可能比对数组中的键进行字符串化甚至更快,甚至可以进行排序:

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)

答案 4 :(得分:1)

ES6:

const repeatMap = {}

array.forEach(arr => {
  const key = JSON.stringify(arr)
  if (repeatMap[key]) {
    repeatMap[key]++
  } else {
    repeatMap[key] = 1
  }
})

const repeatedArrays = Object.keys(repeatMap)
  .filter(key => repeatMap[key] >= 3)
  .map(key => JSON.parse(key))

答案 5 :(得分:1)

您也可以使用单个Array.reduce来执行此操作,其中只有当长度等于3时,才需要推送到result属性:

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

console.log(array.reduce((r,c) => {
  let key = c.join('-')
  r[key] = (r[key] || 0) + 1
  r[key] == 3 ? r.result.push(c) : 0  // if we have a hit push to result
  return r
}, { result: []}).result)             // print the result property

相关问题