Home > OS >  splitting Array with duplicates into two arrays, one for Unique and one for duplicates
splitting Array with duplicates into two arrays, one for Unique and one for duplicates

Time:09-30

I have an array like following simpler example:

array = [1,2,2,3,4,4,4,5,6,7,7,7,8,9]

and I would like to check and separate them into the following arrays:

uniqArray = [1,3,5,6,8,9]
dupArray = [[2,2],[4,4,4],[7,7,7]]

I have tried this




let array = [1,2,2,3,4,4,4,5,6,7,7,7,8,9]

let uniqArray = []
let dupArray = []

let tempArray = []

array.forEach((item, index) => {
  if (item !== array[index   1]) {
    uniqArray.push(item)
    if (tempArray.length > 0) {
      dupArray.push(tempArray)
      tempArray = []
    }
  } else {
    tempArray.push(item)
  }
}
)

console.log(uniqArray) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(dupArray) // [ [ 2 ], [ 4, 4 ], [ 7, 7 ] ]

but as you can see the first instance of the duplicate stays in the uniqArray.

also tried this which actually worked but I am not sure if it is the best solution:




let array = [1,2,2,3,4,4,4,5,6,7,7,7,8,9]

let arrayOfArrays = array.reduce((acc, curr) => {
  if (acc[acc.length - 1].length === 0 || acc[acc.length - 1][0] === curr) {
    acc[acc.length - 1].push(curr)
  } else {
    acc.push([curr])
  }
  return acc
}
, [[]]) // [[ 1 ],[ 2, 2 ],[ 3 ],[ 4, 4, 4 ],[ 5 ],[ 6 ],[ 7, 7, 7 ],[ 8 ],[ 9 ]]



let uniqItems = arrayOfArrays.filter(item => item.length === 1).map(item => item[0]) 
let duplicateItems = arrayOfArrays.filter(item => item.length > 1) 

console.log("~ duplicateItems", duplicateItems) // [ [ 2, 2 ], [ 4, 4, 4 ], [ 7, 7, 7 ] ]
console.log("~ uniqItems", uniqItems) // [ 1, 3, 5, 6, 8, 9 ]

It would be awesome if anyone has a better solution to this!

CodePudding user response:

You can try using collections.Counter:

def getUniqueAndDups(arr):
    c = collections.Counter(arr)
    unique = []
    dups = []
    for item in c:
        if c[item] == 1:
            unique.append(item)
        else:
            dups.append([item]*c[item])
    return unique, dups

>>> uniqueArray, dupArray = getUniqueAndDups([1,2,2,3,4,4,4,5,6,7,7,7,8,9])
>>> uniqueArray
[1, 3, 5, 6, 8, 9]
>>> dupArray
[[2, 2], [4, 4, 4], [7, 7, 7]]
>>> 

CodePudding user response:

let array = [1,2,2,3,4,4,4,5,6,7,7,7,8,9];
//sort the array
array.sort();
let unique = [];
let dupes = [];
let duptemp = [];

//iterative approach using traditional for loop
for(let i = 0; i < array.length; i  ){
   //if the next element in array is equal to current, add current
   //to dupes
   if(i   1 < array.length && array[i   1] === array[i]){
      duptemp.push(array[i]);
   //if next element in array is not equal to current
   //and duptemp is has values, push into dupes and clear temp
   } else if(i   1 < array.length && array[i   1] !== array[i] && duptemp.length > 0) {
      duptemp.push(array[i]);
      dupes.push(duptemp);
      duptemp = [];
   //if at the end of the array and duptemp has values,
   //add to dupes
   } else if(i   1 >= array.length && duptemp.length > 0){
      duptemp.push(array[i]);
      dupes.push(duptemp);
   //it's unique
   } else {
      unique.push(array[i]);
   }
}

console.log(unique);
console.log(dupes);

CodePudding user response:

You can do it with Map

const array = [1, 2, 2, 3, 4, 4, 4, 5, 6, 7, 7, 7, 8, 9];

const countMap = new Map();
// Count the occurence of each item and save it at a map.
for (const number of array) {
  const count = countMap.get(number);
  if (count) countMap.set(number, count   1);
  else countMap.set(number, 1);
}

const unique = [];
const double = [];

// For each item at map, fill the unique and double array
for (const keyValue of countMap.entries()) {
  const count = keyValue[1];
  const number = keyValue[0];
  if (count == 1) {
    unique.push(number);
  } else {
    double.push(Array(count).fill(number));
  }
}

console.log(unique);
console.log(double);

I think this is the most performatic way to do it with a large array, and it don't need to be sorted

  • Related