ES6从对象中获取随机元素而不重复

问题描述 投票:3回答:3

我有一个应该呈现随机颜色的功能,但不重复颜色。

意思是如果随机选择蓝色,则无法再次选择。当然这意味着需要一个默认值。我正在考虑使用switch声明。

这是我目前的代码:

const colors = {
      grey: '#BDC8D1',
      blue: '#0500FF',
      pink: '#FF00C7',
      orange: '#FF7A00'
    }

    const randomColor = () => {
      let keys = Object.keys(colors)
      return colors[keys[keys.length * Math.random() << 0]]
    }
javascript ecmascript-6
3个回答
5
投票

您可以“使用”一系列有效值来返回。通过消费我的意思是,从数组中删除它们。

例如:

// List of all valid values (those that can be returned)
const colors = [ 'red', 'green', 'blue' ];

// The default color (when all others have been "consumed")
const defaultColor = 'black'; 

// The function that returns a random color
const getRandomColor = () => {
    // At least we return a color
    let color = defaultColor;

    // If all colors were previously consumed, we won't need
    // to pick one randomly
    if (colors.length > 0) {
        // We select randomly an index from the colors array
        const index = Math.floor(colors.length * Math.random());

        // We store the color to return
        color = colors[index];

        // We remove it from the array
        colors.splice(index, 1);
    }
    
    return color;
};

console.log(getRandomColor());
console.log(getRandomColor());
console.log(getRandomColor());
console.log(getRandomColor());
console.log(getRandomColor());
console.log(getRandomColor());

此解决方案的明显问题是您无法多次重复使用您的函数。更好的解决方案是创建迭代器。每次应用程序的某些部分需要生成随机的一系列颜色时,您将创建一个新的迭代器,并使用其next方法获取新值。检查以下内容:

// The default color (when all others have been "consumed")
const defaultColor = 'black'; 

const RandomColorIterator = () => {
    // List of all valid values (those that can be returned)
    const colors = [ 'red', 'green', 'blue' ];
    
    return {
        next: () => {
            // At least we return a color
            let color = defaultColor;

            // If all colors were previously consumed, we won't need
            // to pick one randomly
            if (colors.length > 0) {
                // We select randomly an index from the colors array
                const index = Math.floor(colors.length * Math.random());

                // We store the color to return
                color = colors[index];

                // We remove it from the array
                colors.splice(index, 1);
            }

            return color;
        },
    };
};

const iterator1 = RandomColorIterator();
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());

const iterator2 = RandomColorIterator();
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());

我一直在使用箭头功能从父范围中获利。这允许基于每个呼叫访问colors


1
投票

只是为了与众不同并使用一些函数式编程:

const colors = {
      grey: '#BDC8D1',
      blue: '#0500FF',
      pink: '#FF00C7',
      orange: '#FF7A00'
    }


const randomIndex = arr => (Math.random() * arr.length) >> 0


const getColors = (keys = [], times = 0, colors = []) => {
  if (!keys.length || times <= 0) {
    return colors
  }

  const randIndex = randomIndex(keys)

  colors.push(keys[randIndex])
  keys.splice(randIndex, 1)
  times--


  return getColors(keys, times, colors)
}

// select 2 colors
console.log(getColors(Object.keys(colors), 2))

注意:如果你没有改变参数,即keys.splice,那会更好

此外,这是有人提到的.sort方法 - 很酷的主意。

Object.keys(colors).sort((a, b) => {
  const order = [ -1, 0, 1 ]
  return order[(Math.random() * 3) >> 0]
})

0
投票

这是一个实际的实现:

const colors = {
  grey: '#BDC8D1',
  blue: '#0500FF',
  pink: '#FF00C7',
  orange: '#FF7A00'
}



let keysArr = Object.keys(colors);
let keyArrLength = keysArr.length


for (let i = 0; i < keyArrLength; i++) {
  let el = keysArr[Math.floor(Math.random() * keysArr.length)];
  console.log(el);
  let index = keysArr.indexOf(el);
  keysArr.splice(index, 1);
}

希望这很有帮助,如果您有任何疑问,可以发表评论;)。

© www.soinside.com 2019 - 2024. All rights reserved.