0

I have an array which gets updated at times, so the size of the array is arbitrary.

I would like to get a non-duplicate index from the array (note: not the element at index, but just the index).

The program runs every 1000ms, and I'm trying to get a unique index.

This is what I have so far:

randomIndex = data => {
  let rand = Math.floor(Math.random() * data.length);
  if (rand !== Math.floor(Math.random() * data.length)) {
    return rand;
  } else {
    return Math.floor(Math.random() * data.length);
  }
};

Yet still returns duplciate values

Edit

Suppose we have data = ['bob', 'charli', 'kate']

I would like to get a random index e.i. 0 or 1 or 2.

Because I have setInterval(() => {}, 1000) currently i get the same index after 1000s, which is not what I want. So for every second, I need a different index.

Update

Note that when I say no duplicate, what I really mean is that I do not want the same index to appear consecutively.

So say after 1s we have index 1, then the next 1s after, I want either 0 or 2.

9
  • 3
    Could you elaborate on what you mean by 'non-duplicate index'? Commented Sep 20, 2018 at 15:27
  • What are you trying to do in your code? if the if is false, the second Math.random can still return the same value as rand Commented Sep 20, 2018 at 15:28
  • I assume you want a function that returns an array index but that index should not be duplicated?. Always unique?? Commented Sep 20, 2018 at 15:30
  • @IsaacVidrine Please check the update Commented Sep 20, 2018 at 15:30
  • @F.bernal Yes, just the index which is different every 1000s Commented Sep 20, 2018 at 15:31

4 Answers 4

1

You need to keep track of a history of indexes to avoid duplicates. This example also uses recursion to keep trying to find a unique index. If there are none unique left, reset the history array. Hope this helps!

EDIT:

Looks like you don't actually need to keep track of 'history', rather just the last chosen index. This should get you where you need to be.

let people = ['bob', 'charli', 'kate', 'bobby', 'jake', 'john', 'jerry', 'isaac'];
let lastIndex;

getRandIndex = (data) => {
  let rand = Math.floor(Math.random() * (data.length));
  if (!lastIndex) {
    lastIndex = rand;
    return rand
  }
  if (rand != lastIndex) {
    lastIndex = rand;
    return rand;
  } else {
    return getRandIndex(data);
  }
};

setInterval(() => {
  console.log(getRandIndex(people))
}, 1000)

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

8 Comments

That function has a problem. Infinite when all the unique indexes where covered.
I think it has to be return getRandIndex(data);
This is still returning duplicates. Tried it
The reason why this returns duplicate is when we clear the array, and the next random number generated, is still the same as previosuly removed number
Sebastian was right, needed to add that return statement. Check updated answer, should work.
|
0

Just this function:

let people = ['bob', 'charli', 'kate', 'bobby', 'jake', 'john', 'jerry', 'isaac'];

getRandIndex = (data, noRepeat) => {
  rand = Math.floor(Math.random() * (data.length));
  while(noRepeat === rand) {
    rand = Math.floor(Math.random() * (data.length));
  }
  
  return rand;
  
};

let r = -1;

setInterval(() => {  
  r = getRandIndex(people, r);
  
  console.log(r);
  
}, 1000)

Comments

0

To do your task you need to use the do...while language construct, it will keep generating a new random number if the current random number is the same as the last one.

Here's a snippet to illustrate:

In the snippet I'll use the setInterval method which doesn't allow the callback function(the first argument) to return a value, so you can assign the generated number to a variable and you can stop the interval using the reference variable(the variable that the setInterval method is assigned to) by using the clearInterval method. And also, I end the interval after 5 seconds.

var data = ['bob', 'charli', 'kate'],
    l = data.length,
    lastIndex = -1,
    counter = 0;
intervalID = setInterval(getRandom, 1000);
function getRandom() {
  do {
    var r = Math.floor(Math.random() * l);
  } while (r === lastIndex);
  lastIndex = r;
  console.log('data: ' + data[r] + ' | random_number: ' + r);
  if(++counter === 5) {
    clearInterval(intervalID);
  }
}

Hope I pushed you further.

Comments

0

A simple and clean way to do this

let previous = 0;
getRandIndex = (data) => {
  const rand = Math.floor(Math.random() * data.length);
  if(rand == previous) return getRandIndex(data);
  previous = rand;
  return rand;
};

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.