javascript - ES6 从对象中获取随机元素,不重复
问题描述
我有一个应该渲染随机颜色的函数,但不重复颜色。
这意味着如果蓝色是随机选择的,则无法再次选择。当然,这意味着需要有一个默认值。我正在考虑使用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]]
}
解决方案
您可以“使用”一组要返回的有效值。通过消费我的意思是,从数组中删除它们。
例如:
// 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
在每次呼叫的基础上进行访问。
推荐阅读
- java - 如何在java中增加张量的维度?
- java - 有没有办法将数组对象添加到类中?
- python - Flask 中有 python GIL 吗?
- java - 查找arraylists java的所有可能组合
- c# - 相同类型的 System.InvalidCastException?
- python - 以python方式将值从一个数字转移到另一个数字,直至最大值
- javascript - 如何使用与 JavaScript 的用户交互将图像更改为同一 HTML 中的另一个图像?
- python - “硬币”不动
- javascript - 不明白为什么这个事件监听器应该进入循环
- python - TeleBot:“发生连接错误