2016-09-20 3 views
2

Мне интересно, как можно было бы удалить уникальные элементы из массива. Например:Javascript - Удалить уникальные элементы из массива

var arr = [1, 2, 2, 4, 4] вернет [2, 2, 4, 4]. Где [1, 2, 3] вернет [], потому что все элементы уникальны.

Я считаю, что мне нужно проверить каждый элемент с любым другим элементом массива, но я не уверен, как это сделать.

Спасибо!

+0

Создайте объект, ключи которого являются элементами массива, а значения - это количество раз, которое элемент появляется в массиве. Удалите все элементы из исходного массива, чей счет равен 1. – Barmar

+0

Благодарим за редактирование – TylerMayfield

+0

Если вы ищете SO, вы сможете найти много вопросов, объясняющих, как подсчитать повторения. – Barmar

ответ

4

С ES6, вы могли бы использовать Array#map и рассчитывать значения с Array#forEach.

Позже используйте Array#filter и проверьте количество.

Если больше 1 возвращение true (укажите элемент в результирующем наборе), в противном случае возвратите false (не включайте элемент в результирующий набор).

function getNotUnique(array) { 
 
    var map = new Map(); 
 
    array.forEach(a => map.set(a, (map.get(a) || 0) + 1)); 
 
    return array.filter(a => map.get(a) > 1); 
 
} 
 

 
console.log(getNotUnique([1, 2, 2, 4, 4])); 
 
console.log(getNotUnique([1, 2, 3]));

+1

, даже без ES6, используя 'Object' для хранения счетчиков будет (в общем случае) более эффективным, чем два вложенных цикла. – Alnitak

+0

Это прекрасно работает! Не собираюсь врать, хотя я не понимаю, почему. Я javascript noob! – TylerMayfield

+0

@TylerMayfield ИМХО вы приняли неправильный ответ. Это очень просто - он просто создает подсчет «Карта» значений ->, а затем берет каждое значение из исходного массива, чей счет больше одного. – Alnitak

0

Вот реализация (с использованием https://stackoverflow.com/a/5668029/4202031)

function removeUnique(arr) { 
    var counts = {} 

    for(var i = 0; i< arr.length; i++) { 
     var num = arr[i] 
     counts[num] = counts[num] ? counts[num]+1 : 1 
    } 

    var result = [] 
    for(var key in counts) { 
    if(Object.prototype.hasOwnProperty.call(counts, key) && counts[key] > 1 { 
     result.push(key) 
    } 
    } 

    return result 
} 


var arr = [1, 2, 3] 
var arr2 = [1, 1, 2, 2, 4, 6, 4] 

console.log(removeUnique(arr)) // [] 
console.log(removeUnique(arr2)) // [ '1', '2', '4' ] 
0

Вы могли бы сделать что-то вроде этого (строго с использованием массивов):

var arr = [1,2,3,4,4]; 
var temp = []; 
var to_keep = []; 
for(var x = 0; x < arr.length; x++){ 
    if(temp.indexOf(arr[x]) > -1) { 
    if(to_keep.indexOf(arr[x]) == -1) 
     to_keep.push(arr[x]); 
    } else if(temp.indexOf(arr[x]) == -1) temp.push(arr[x]); 
} 

for(var y = 0; y < arr.length; y++){ 
    if(to_keep.indexOf(arr[y]) == -1){ 
    arr.splice(y,1); 
    y--; 
    } 
} 

// arr = [4,4]; 
1

Ниже основной и легко понять, для удаления уникальной элементы из массива.

function removeUnique(arr) { 
 
\t var newArr = []; 
 
\t for (var i = 0; i < arr.length; i++) { 
 
\t \t var count = 0; 
 
\t \t for (var j = 0; j < arr.length; j++) { 
 
\t \t \t if (arr[j] == arr[i]) { 
 
\t \t \t \t count++; 
 
\t \t \t } 
 
\t \t } 
 
\t \t if (count >= 2) { 
 
\t \t \t newArr.push(arr[i]); 
 
\t \t } 
 
\t } 
 
    return newArr; 
 
} 
 
console.log(removeUnique([1, 2, 2, 4, 4]));

+0

Другие ответы работали, но это первый, который я действительно понимаю. Другие создают объекты, которые я никогда не делал с массивом: | – TylerMayfield

+0

Согласно вашему вопросу, я понял, что вы новичок. Так добавил простой и легкий ответ. – Abhijeet

+0

простой, и _very inefficient_ - это O (n^3) !! – Alnitak

0

Итерация через массив, использовать значение в качестве индекса в объект и приращения для каждого случая в оригинале. Затем перейдите через объект и вытащите те, у которых итоговые значения больше одного. Должен работать для строковых и числовых типов.

function dupsOnly(a) { 
    var T = {}; 
    for (var i = 0; i < a.length; i++) { 
     if (a[i] in T) 
      T[a[i]] += 1; 
     else 
      T[a[i]] = 1; 
    } 
    var D = []; 
    for (var t in T) { 
     if (T[t] > 1) 
      D.push(t); 
     while (T[t] > 1) { 
      T[t] -= 1; 
      D.push(t); 
     } 
    } 
    return D; 
} 
0
var arr = [1, 2, 2, 4, 4] 

var dict_with_count = {} 
for (var i=0; i<arr.length; i++){ 
    dict_with_count[arr[i]] = 0 
} 

for (var i=0; i<arr.length; i++){ 
    dict_with_count[arr[i]] += 1 
} 

var new_list = []; 

for (key in dict_with_count){ 
    if (dict_with_count[key] > 1){ 
     for (var j=0; j<dict_with_count[key]; j++){ 
      new_list.push(key) 
     } 
    } 
} 

console.log(new_list) 
0

Это должно сделать это;

var arr = [1, 2, 2, 4, 4], 
 
    unq = arr.map((e,i,a) => a.filter(f => f === e).length) 
 
      .reduce((p,c,i) => c === 1 ? p : p.concat(arr[i]) ,[]); 
 
console.log(unq);

1

Это старый вопрос, но стандартный способ ES6 должен бы использовать set:

const unique_values = [...new Set([1, 2, 2, 4, 4])] 
>>> [1, 2, 4] 

Набор представляет собой структуру данных, предназначенный для хранения только уникальные значения и является стандартом для большинства языков. В приведенном выше фрагменте я использовал spread operator для создания нового массива из содержимого набора.

Обратите внимание, что Set внутренне использует оператор ===, поэтому применение этого для коллекции объектов или вложенных массивов не будет работать, поскольку они сравниваются по ссылке.

Однако коллекция примитивных типов действительно хорошо работает с Set.

Смежные вопросы