4

I want to remove duplicates from an array without changing its length. If there is a duplicate, I want to generate a new random number on that index. However because that number could already exists, I need to generate it again until it becomes a unique number.

var arr = [5, 5, 5, 4, 4];
let counter = 0;
for (let i = 0; i < arr.Length; i++) {
  for (let j = i + 1; j < arr.Length; j++) {
    if (arr[i] === arr[j]) {
      arr[j] = Math.floor(Math.random() * 10);
      counter++;
    }
  }
  counter = 0;
}
customcommander
  • 17,580
  • 5
  • 58
  • 84
zana10
  • 113
  • 1
  • 8
  • Create an array of numbers, then shuffle it, then pop() unique random numbers to fill your holes. – dandavis Oct 25 '20 at 20:02
  • Does this answer your question? [Create an array with random values](https://stackoverflow.com/questions/5836833/create-an-array-with-random-values) – Randy Casburn Oct 25 '20 at 20:05

4 Answers4

2

this is the solution :

var arr = [5, 5, 5, 4, 4];

const replaceduplicates=(arr)=>{
    let i =1;
     while(i < arr.length -1 ){
         const currentElement=arr[i]
         const indexOfcurrentElement= arr.indexOf(currentElement)
     
         if(indexOfcurrentElement > -1) {
             let newValue=Math.floor(Math.random() * 10 + arr[i-1])
             while( arr.indexOf(newValue) > -1)
             {
                 newValue=Math.floor(Math.random() * 10 )
             }
             arr[i] = newValue;
             i++
         }
     }
     return arr
}

//this is how I tested basically this will run for ever 
let found=false
while(!found ){
    const arrResponse =replaceduplicates(arr)
    for (let i = 0; i < arrResponse.length; i++) {
        for (let j = i+1; j < arrResponse.length; j++) {
           if(arrResponse[i] == arrResponse[j]) found = true
        }
        
    }
    console.log('no duplicates')
}

سعيد
  • 1,547
  • 1
  • 14
  • 32
2

previousElements contain the elements of arr that come before the current index, and otherElements contain all the other elements of arr aside from the current index. a new random number is generated if there has been an instance already. the new random number is then compared with all the rest of the elements of arr to avoid changing the first instance of a number. in the example provided, index 3 will always remain as 4.

var arr = [5, 5, 5, 4, 4];

for (let i = 0; i < arr.length; i++) {
    let previousElements = arr.slice(0, i);
    let otherElements = JSON.parse(JSON.stringify(arr));
    otherElements.splice(3, 1);

    if (previousElements.includes(arr[i])) {
        arr[i] = Math.floor(Math.random() * 10);

        while (otherElements.includes(arr[i])) {
            arr[i] = Math.floor(Math.random() * 10);
        }
    }
}

console.log('arr: ' + JSON.stringify(arr));

sample output: [5,8,2,4,3]

sample output: [5,0,1,4,8]

Simon
  • 369
  • 1
  • 9
2

Use a Set or array or object to keep track of the values already seen and a while loop to get new unique value

const arr = [5, 5, 5, 4, 4];
const seen = new Set();// only holds unique values, even when add duplicates

arr.forEach((n,i) => {      
  while(seen.has(n)){
   arr[i] = n = Math.floor(Math.random() * 10);
  } 
  seen.add(n);
});

console.log(arr)
charlietfl
  • 170,828
  • 13
  • 121
  • 150
1

Use a while loop instead of an if statement to keep checking the value until it is not equal to the previous value.

Though you would need to add an additional check after the changing the number to the random number to see if that random number is not in the array already.

const hasDuplicateNumbers = (number, numbers) => 
  numbers.filter(item => item === number).length > 1;

let arr = [5, 5, 5, 4, 4];
for (let i = 0; i < arr.length; i++) {
  for (let j = i + 1; j < arr.length; j++) {
    if (i === j) {
      continue;
    }
    while(hasDuplicateNumbers(arr[j], arr)) {
      arr[j] = Math.floor(Math.random() * 10);
    }
  }
}

console.log(arr);
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32