Как получить неповторяющийся индекс массива в js? - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть массив, который обновляется время от времени, поэтому размер массива произвольный.

Я хотел бы получить неповторяющийся индекс из массива (примечание: не элемент в индексе,но только индекс).

Программа запускается каждые 1000 мс, и я пытаюсь получить уникальный индекс.

Это то, что у меня есть:

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

И все же возвращает двойные значения

Редактировать

Предположим, у нас есть data = ['bob', 'charli', 'kate']

Я хотел бы получитьслучайный индекс ei 0 или 1 или 2.

Поскольку у меня есть setInterval(() => {}, 1000), в настоящее время я получаю тот же индекс после 1000 с, что не то, что я хочу.Поэтому на каждую секунду мне нужен другой индекс.

Обновление

Обратите внимание, что когда я говорю «нет дубликатов», я имею в виду, что я не хочу, чтобы один и тот же индекс появлялся последовательно.

Так, например, после 1 с у нас есть индекс 1, затем через 1 с я хочу либо 0, либо 2.

Ответы [ 4 ]

0 голосов
/ 20 сентября 2018

Простой и чистый способ сделать это

let previous = 0;
getRandIndex = (data) => {
  const rand = Math.floor(Math.random() * data.length);
  if(rand == previous) return getRandIndex(data);
  previous = rand;
  return rand;
};
0 голосов
/ 20 сентября 2018

Для выполнения вашей задачи вам нужно использовать языковую конструкцию do...while, она будет генерировать новое случайное число, если текущее случайное число совпадает с последним.

Вот фрагмент кода для иллюстрации:

В этом фрагменте я буду использовать метод setInterval, который не позволяет функции обратного вызова (первый аргумент) возвращать значение, поэтому вы можете присвоить сгенерированный номер переменнойи вы можете остановить интервал, используя опорную переменную (переменную, которой назначен метод setInterval), используя метод clearInterval.И также, я заканчиваю интервал через 5 секунд.

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

Надеюсь, я подтолкнул вас дальше.

0 голосов
/ 20 сентября 2018

Только эта функция:

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)
0 голосов
/ 20 сентября 2018

Вам необходимо отслеживать историю индексов, чтобы избежать дублирования.В этом примере также используется рекурсия для продолжения поиска уникального индекса.Если не осталось ни одного уникального, сбросьте массив истории.Надеюсь, это поможет!

РЕДАКТИРОВАТЬ:

Похоже, вам на самом деле не нужно отслеживать «историю», а только последний выбранный индекс.Это должно привести вас туда, где вы должны быть.

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