从 JavaScript 数组中获取随机项
技术背景
在 JavaScript 开发中,有时需要从数组中随机选取一个元素,例如随机展示图片、随机选择问题等。以下将介绍多种实现从 JavaScript 数组中获取随机项的方法。
实现步骤
1. 定义数组原型方法
通过为 Array
原型添加一个 random
方法,可以方便地从数组中获取随机项。
1 2 3
| Array.prototype.random = function () { return this[Math.floor((Math.random()*this.length))]; }
|
可以直接在数组上调用该方法:
也可以用于预定义的数组:
1 2
| var list = [2,3,5]; list.random();
|
2. 定义自定义函数
定义一个接受数组作为参数并返回随机元素的函数。
1 2 3 4
| function get_random (list) { return list[Math.floor((Math.random()*list.length))]; } get_random([2,3,5]);
|
3. 使用 underscore 或 loDash
可以使用 _.sample
方法获取随机元素,也可以手动使用 _.random
方法。
1 2 3 4 5 6 7
| var randomArray = [ '#cc0000', '#00cc00', '#0000cc' ];
var randomElement = _.sample(randomArray);
var randomElement = randomArray[_.random(randomArray.length - 1)];
|
还可以使用 _.shuffle
方法打乱整个数组并获取第一个元素。
1
| var firstRandomElement = _.shuffle(randomArray)[0];
|
4. 使用 jQuery
虽然不推荐使用 jQuery 来解决这个问题,但可以通过扩展 jQuery 实现。
1 2 3 4 5 6 7 8 9 10 11 12 13
| (function($) { $.rand = function(arg) { if ($.isArray(arg)) { return arg[$.rand(arg.length)]; } else if (typeof arg === "number") { return Math.floor(Math.random() * arg); } else { return 4; } }; })(jQuery); var items = [523, 3452, 334, 31, 5346]; var item = jQuery.rand(items);
|
5. 其他方法
可以使用双波浪号 ~~
或按位或 |
来获取最接近的整数。
1 2 3 4 5 6
| function rand(items) { return items[~~(items.length * Math.random())]; } function rand(items) { return items[items.length * Math.random() | 0]; }
|
还可以通过打乱数组并获取第一个元素的方式来实现。
1
| var item = items.sort(function() {return 0.5 - Math.random()})[0];
|
使用箭头函数可以使代码更简洁。
1
| let item = items.sort(() => 0.5 - Math.random())[0];
|
也可以先定义一个随机数生成函数,再使用该函数获取随机索引。
1 2 3 4 5 6 7 8
| function rand(min, max) { var offset = min; var range = (max - min) + 1; var randomNumber = Math.floor( Math.random() * range) + offset; return randomNumber; } var randomNumber = rand(0, items.length - 1); var randomItem = items[randomNumber];
|
6. 在 Node.js 中使用 unique-random-array
在 Node.js 中,可以使用 unique-random-array
包来获取随机元素。
7. 自定义模块
可以创建一个包含多个数组操作方法的模块。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const ArrayRandomModule = { random: function (array) { return array[Math.random() * array.length | 0]; }, pick: function (array, i) { return array.splice(i >= 0 ? i : Math.random() * array.length | 0, 1)[0]; }, shuffle: function (array) { for (var i = array.length; i > 0; --i) array.push(array.splice(Math.random() * i | 0, 1)[0]); return array; } }
|
核心代码
以下是最常用的直接获取随机项的代码:
1
| var randomItem = items[Math.floor(Math.random()*items.length)];
|
最佳实践
- 如果只需要偶尔获取随机项,直接使用
Math.random()
和 Math.floor()
组合的方法是最简单的。 - 如果需要频繁从不同数组中获取随机项,可以考虑为
Array
原型添加方法或定义自定义函数。 - 如果项目中已经使用了 underscore 或 loDash,使用它们提供的方法会更方便。
常见问题
- 修改数组原型的影响:为
Array
原型添加方法可能会导致命名冲突,影响其他代码。在大型项目中,建议使用自定义函数的方式。 - 性能问题:使用
sort
方法打乱数组的性能较低,不适合处理大型数组。在性能敏感的场景中,建议使用其他方法。