6

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.

6
  • 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. Commented Sep 20, 2016 at 16:16
  • If you search SO, you should be able to find many questions that explain how to count the repetitions. Commented Sep 20, 2016 at 16:17
  • Possible duplicate of Unique values in an array Commented Sep 20, 2016 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. Commented Sep 20, 2016 at 16:33
  • And another duplicate: stackoverflow.com/questions/9229645/… and another where the most upvoted answer is not the acepted one. This one is actually better, I think, though I found it second. Commented Sep 20, 2016 at 16:36

9 Answers 9

6

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

Sign up to request clarification or add additional context in comments.

4 Comments

even without ES6, using an Object to store the counts would be (in the general case) more efficient that two nested loops.
This works perfectly! Not going to lie though, I don't really understand why. I'm a javascript noob!
@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.
Whoops, I accepted this one first. I thought I could accept more than 1.
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]));

6 Comments

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 :|
According to your question, I understood that you were beginner. So added simple and easy answer.
simple, and very inefficient - it's O(n ^ 3) !!
I didn't say it was efficient. It was easy to understand.
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.
|
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.

Comments

1

The code is below returns all duplicated values

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

Comments

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

Comments

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

Comments

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)

Comments

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

Comments

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

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.