Найти, если два массива повторяются в массиве, а затем выбрать их - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть несколько массивов в основном / родительском массиве, например:

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

Я нашел нечто подобное здесь но он использует underscore.js и lodash.

Как я могу это сделать с помощью javascript или даже jquery (если нужно)?

Ответы [ 6 ]

0 голосов
/ 24 ноября 2018

Вы также можете сделать это с помощью единственного Array.reduce, когда вы только подтолкнете к свойству result, если длина равна 3:

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
0 голосов
/ 24 ноября 2018

Для другого дубля вы можете сначала отсортировать свой список, затем один раз просмотреть и выбрать элементы, отвечающие вашим требованиям.Это, вероятно, будет быстрее, чем строковые ключи из массива, даже с сортировкой:

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)
0 голосов
/ 24 ноября 2018

Попробуйте это

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

Сложность времени O (n) (один проход массива функцией фильтрации).Вдохновленный ответом Нитиш .

Пояснение

(r={}, a=>...) вернет последнее выражение после запятой (то есть a=>...) (например, (5,6)==6).В r={} мы устанавливаем один раз временный объект, где будем хранить уникальные ключи.В функции фильтра a=>... в a у нас есть текущий array элемент.В r[a] JS implicity приводят a к строке (например, 1,17).Затем в !(2-(r[a]=++r[a]|0)) мы увеличиваем счетчик элемента вхождения a и возвращаем true (как значение функции фильтра), если элемент a встречался 3 раза.Если r[a] не определено, ++r[a] возвращает NaN и далее NaN|0=0 (также number|0=number).r[a]= инициализирует значение первого счетчика, если мы его опускаем, ++ только установит NaN в r[a], что не является приращением (поэтому нам нужно установить ноль в init).Если мы удалим 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));
0 голосов
/ 24 ноября 2018

Вы можете использовать Object.reduce, Object.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)

ИЛИ может быть только с 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)
0 голосов
/ 24 ноября 2018

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))
0 голосов
/ 24 ноября 2018

Вы можете взять 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; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...