5

I am wondering how one would go about removing unique elements from an array. For example:

var arr = [1, 2, 2, 4, 4] would return [2, 2, 4, 4]. Where [1, 2, 3] would return [] because all elements are unique.

I believe I need to check each element with every other element in the array, but I'm not sure how to go about this.

Thanks!

Barmar
  • 741,623
  • 53
  • 500
  • 612
TylerMayfield
  • 83
  • 1
  • 1
  • 9
  • Create an object whose keys are the array elements, and values are the count of times the element appears in the array. Remove all the elements from the original array whose count is 1. – Barmar Sep 20 '16 at 16:16
  • If you search SO, you should be able to find many questions that explain how to count the repetitions. – Barmar Sep 20 '16 at 16:17
  • Possible duplicate of [Unique values in an array](http://stackoverflow.com/questions/1960473/unique-values-in-an-array) – VLAZ Sep 20 '16 at 16:32
  • ^ the most upvoted answer there (which is not the accepted one) has a clear example of how to get _only_ unique items. If you want to _remove_ them, you literally just have to invert the uniqueness check result. – VLAZ Sep 20 '16 at 16:33
  • And another duplicate: http://stackoverflow.com/questions/9229645/remove-duplicates-from-javascript-array/9229821#9229821 and another where the most upvoted answer is not the acepted one. This one is actually better, I think, though I found it second. – VLAZ Sep 20 '16 at 16:36
  • Hey vlaz, I searched for awhile trying to find a solution. I encountered both that you posted. The first one converts the array into an object which I've never done and not really sure how to go about doing. It appears the second one uses jQuery for the first solution and then the second solution is a bunch of advanced javascript that I'm not even sure where to start. Sorry, I'm pretty new to javascript. – TylerMayfield Sep 20 '16 at 16:55

9 Answers9

5

With ES6, you could use a Array#map and count the values with Array#forEach.

Later use Array#filter and check the count.

If greater than 1 return true (include the item in the result set), otherwise return false (do not include item in the result set).

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] ));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • 1
    even without ES6, using an `Object` to store the counts would be (in the general case) more efficient that two nested loops. – Alnitak Sep 20 '16 at 16:36
  • This works perfectly! Not going to lie though, I don't really understand why. I'm a javascript noob! – TylerMayfield Sep 20 '16 at 16:44
  • @TylerMayfield IMHO you accepted the wrong answer. This one is very simple - it just builds a `Map` of values -> counts, and then takes every value from the original array whose count is greater than one. – Alnitak Sep 20 '16 at 17:15
  • Whoops, I accepted this one first. I thought I could accept more than 1. – TylerMayfield Sep 20 '16 at 17:19
2

Below is basic and easy to understand for removing unique elements from array.

function removeUnique(arr) {
 var newArr = [];
 for (var i = 0; i < arr.length; i++) {
  var count = 0;
  for (var j = 0; j < arr.length; j++) {
   if (arr[j] == arr[i]) {
    count++;
   }
  }
  if (count >= 2) {
   newArr.push(arr[i]);
  }
 }
    return newArr;
}
console.log(removeUnique([1, 2, 2, 4, 4]));
Abhijeet
  • 4,069
  • 1
  • 22
  • 38
  • The other answers worked as well, but this is the first one I actually understand. The others are creating objects which is something I've never done with an array :| – TylerMayfield Sep 20 '16 at 16:50
  • According to your question, I understood that you were beginner. So added simple and easy answer. – Abhijeet Sep 20 '16 at 16:52
  • simple, and _very inefficient_ - it's O(n ^ 3) !! – Alnitak Sep 20 '16 at 16:53
  • 1
    I didn't say it was efficient. It was easy to understand. – Abhijeet Sep 20 '16 at 16:55
  • The `indexOf` call in between the two loops doesn't work - you put the braces in the wrong place. And if it did would actually break the code by making it only return one entry for each non-unique value in the original array. It's an unnecessary test and is what makes this code O(n^3) instead of O(n^2), but still worse than the O(n) that using a `Map` gives you. – Alnitak Sep 20 '16 at 17:09
  • Thanks for input @Alnitak – Abhijeet Sep 20 '16 at 17:20
1

This should do it;

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

However on a second thought the following might be even more readable and efficient. We are in fact using one of the rare cases in which we can utilize laziness in JS through a short circuit.

var r = [1,2,2,4,4].filter((e,i,a) => a.lastIndexOf(e) != i || a.indexOf(e) != i);
console.log(r);

So the a.indexOf(e) != i portion only runs for the unique elements and the last encountered non-unique element. Cool.

Redu
  • 25,060
  • 6
  • 56
  • 76
1

The code is below returns all duplicated values

const getDuplicatedVals = (data) => data.filter( (x) => data.indexOf(x) != data.lastIndexOf(x))

d4rkm3z
  • 11
  • 2
0

Here is an implementation (using 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' ]
Community
  • 1
  • 1
n1ru4l
  • 488
  • 1
  • 10
  • 29
0

You could do something like this (strictly using arrays):

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];
Ryan Willis
  • 624
  • 3
  • 13
0

Iterate through the array, use the value as an index into an object and increment for each occurrence in the original. Then iterate through the object and pull out those with totals greater than one. Should work for string and numeric types.

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;
}
Yimin Rong
  • 1,890
  • 4
  • 31
  • 48
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)
SuperNova
  • 25,512
  • 7
  • 93
  • 64
0
#include <stdio.h>

int main() {
    int n;

    printf("Enter the length of the array: ");
    scanf("%d", &n);

    int array[n];
    int frequency[1000] = {0}; // Assuming element range from 0 to 999

    printf("Enter the elements of the array:\n");
    for (int i = 0; i < n; i++) {
        scanf("%d", &array[i]);
        frequency[array[i]]++;
    }

    int newSize = 0;

    // Remove unique elements directly in the original array
    for (int i = 0; i < n; i++) {
        if (frequency[array[i]] > 1) {
            array[newSize] = array[i];
            newSize++;
            frequency[array[i]] = 0; // Mark as copied
        }
    }

    printf("Array after deleting unique elements:\n");
    for (int i = 0; i < newSize; i++) {
        printf("%d ", array[i]);
    }

    return 0;
}
toyota Supra
  • 3,181
  • 4
  • 15
  • 19
sarath
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 21 '23 at 07:07