Fisher Yates Shuffle, но с использованием функций массива Javascript

Я смотрел на предложения случайного выбора Фишера Йейтса на StackOverflow после исключения arr.sort(v => Math.random() - 0.5) из-за отсутствия случайности в последнем.

Функции Фишера Йейтса выглядят нормально, но используются в циклах while и т. Д. В качестве альтернативы, функции массива javascript (отображение, сокращение и т. Д.) Имеют очевидную проблему продвижения вперед, поэтому вам по-прежнему требуется доступ к длине массива, чтобы внедрить его ( что явно отнимает немного времени).

Итак, я написал свой собственный Фишер Йейтс, используя сокращение.

Я хотел это

  1. Измените исходный массив, как это делает sort.

  2. Верните исходный массив, чтобы я мог поместить его в начало цепочки функций массива, например let myarr = [1, 2, 3, 4, 5]; let newARR = fyRandArr(myarr).filter(v => v !== 3);

  3. Последняя итерация сокращения не требует каких-либо действий, потому что этот элемент уже случайным образом находится в позиции.

Моя функция работает и делает все, что указано выше.

Я программист-любитель, поэтому не уверен, что это считается хорошо написанным. Мне не у кого спросить. как это может быть улучшено?

       const fyRandArr = arr =>
        arr.reduce((A, v, i, a) => {
            let r;
            return i === A.lM1 ? a : (r = i + Math.floor(Math.random() * (A.l - i)), [a[i], a[r]] = [a[r], a[i]], A);
        }, {l: arr.length, lM1: arr.length -1});

Очевидно, что если вам нужна чистая функция, то есть создание нового массива в случайном порядке, вы можете просто извлечь бит уменьшения и не беспокоиться о fyRandArr.

1 ответ

Для полноты картины в codereview установлено следующее:

  1. оператор запятой не нравится
  2. аккумуляторы разных типов не одобряются
  3. постоянная передача длины в накопитель объектов более «дорогостоящая», чем вычисление длины на каждой итерации.

При этом я записал следующее:

      const fyRandArr = arr =>
        arr.reduce((a, v, i) => {
            let r, l = a.length;
            [a[i], a[r = (i + Math.random() * (l - i)) | 0]] = [a[r], a[i]];
            return a;
        }, arr);

или

      const fyRandArr = arr => {
    arr.map((v, i, a) => {
        let r, l = a.length;
        [a[i], a[r = (i + Math.random() * (l - i)) | 0]] = [a[r], a[i]];
        return a[i];
    });
    return arr;
};
Другие вопросы по тегам