【问题标题】:How to shuffle an array without moving FALSY elements?如何在不移动 FALSY 元素的情况下对数组进行洗牌?
【发布时间】:2020-11-22 11:42:43
【问题描述】:

这是我的尝试;稍微修改的 Fisher-Yates 算法。我不确定如何确保它是随机的。

const shuffleWithoutMovingFalsies = array => {
  const newArray = [...array];
  const getRandomValue = (i, N) => ~~(Math.random() * (N - i) + i);
  newArray.forEach((elem, i, arr, j = getRandomValue(i, arr.length)) => arr[i] && arr[j] && ([arr[i], arr[j]] = [arr[j], arr[i]]));
  return newArray;
}

const array = [1, 2, null, 3, null, null, 4, 5, 6, null];

const shuffledArray = shuffleWithoutMovingFalsies(array);

console.log(shuffledArray);

我所做的只是添加arr[i] && arr[j] && 作为检查以确保要交换的两个元素都不是falsy

【问题讨论】:

    标签: javascript arrays algorithm random shuffle


    【解决方案1】:

    这阻止了它成为一个公平的洗牌。例如,对于数组[1, null, 2]1 应该有 50% 的机会保持原状,并有 50% 的机会与 2 交换,但相反,拆分是 ⅔–⅓。

    只要辅助内存不成问题,我建议提取元素,打乱它们,然后为了简单起见将它们放回去:

    const shuffle = arr => {
        for (let i = 0; i < arr.length - 1; i++) {
            const j = i + Math.floor(Math.random() * (arr.length - i));
            [arr[i], arr[j]] = [arr[j], arr[i]];
        }
    };
    
    const shuffleTruthy = arr => {
        const truthy = arr.filter(Boolean);
        shuffle(truthy);
    
        let j = 0;
    
        for (let i = 0; i < arr.length; i++) {
            if (arr[i]) {
                arr[i] = truthy[j++];
            }
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 2013-12-19
      • 1970-01-01
      相关资源
      最近更新 更多