翼度科技»论坛 编程开发 JavaScript 查看内容

d3.shuffle、Fisher–Yates算法以及js 中的slice

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
1.d3.shuffle

D3.shuffle() 方法用于将数组中的元素随机排序。它使用 Fisher–Yates 洗牌算法,该算法是无偏的,具有最佳的渐近性能(线性时间和常数内存)。
D3.shuffle() 方法的语法如下:
  1. d3.shuffle(array, [start, end])
复制代码
其中:

  • array 是原数组。
  • start 是开始索引,默认为 0。
  • end 是结束索引,默认为数组的长度。
如果 end 是负数,则它表示从数组末尾开始向前计算的索引。
D3.shuffle() 方法返回的数组是一个新数组,它包含原数组中元素的随机排列。
D3.shuffle() 方法的常见用法如下:

  • 将数组中的元素随机排序:
  1. const arr = [1, 2, 3, 4, 5];
  2. const shuffledArr = d3.shuffle(arr);
复制代码

  • 将数组中的元素随机排序,并只返回指定范围内的元素:
  1. const arr = [1, 2, 3, 4, 5];
  2. const shuffledArr = d3.shuffle(arr, 1, 3);
复制代码
D3.shuffle() 方法还可以与其他方法一起使用来实现更复杂的功能。例如,可以使用 D3.shuffle() 方法和 D3.map() 方法来随机选择数组中的元素。
  1. const arr = [1, 2, 3, 4, 5];
  2. const shuffledArr = arr.map(x => d3.shuffle(arr)[0]);
复制代码
在上述示例中,D3.shuffle() 方法用于随机选择 arr 数组中的元素。D3.map() 方法用于将 shuffledArr 数组中的每个元素映射到一个新的数组中。
以下是 D3.shuffle() 方法的执行原理:

  • D3.shuffle() 方法将原数组中的元素复制到一个新数组中。
  • 使用 Fisher–Yates 洗牌算法对新数组中的元素进行随机排序。()
  • 返回随机排序后的数组。
因此,D3.shuffle() 方法将返回一个包含原数组中元素的随机排列。
2.fisher-yate 洗牌算法


Fisher–Yates 洗牌算法是一种随机排序算法,它使用以下步骤来将数组中的元素随机排序:

  • 从数组中随机选择一个元素,并将其移到数组的末尾。(这里实际上是和末尾调换)
  • 重复步骤 1,直到数组中的所有元素都被移到末尾。(第一部改变之后,最后一位不变)
Fisher–Yates 洗牌算法是无偏的,具有最佳的渐近性能(线性时间和常数内存)。
以下是 Fisher–Yates 洗牌算法的 JavaScript 实现:
  1. function shuffle(arr) {
  2.   for (let i = arr.length - 1; i >= 0; i--) {
  3.     const j = Math.floor(Math.random() * (i + 1));
  4.     [arr[i], arr[j]] = [arr[j], arr[i]];
  5.   }
  6.   return arr;
  7. }
复制代码
该算法使用 Math.random() 方法来生成一个随机数,该数用于选择要移到末尾的元素。然后,算法将该元素与数组末尾的元素交换位置。
以下是 Fisher–Yates 洗牌算法的示例:
  1. const arr = [1, 2, 3, 4, 5];
  2. const shuffledArr = shuffle(arr);
  3. console.log(shuffledArr); // [5, 4, 3, 2, 1]
复制代码
在上述示例中,shuffledArr 数组将包含原数组中元素的随机排列。
来源:stackoverflow
3.示例

示例一:使用 d3.shuffle 来模拟一次扑克牌的洗牌过程。我们可以先创建一个包含52张扑克牌的数组,然后用 d3.shuffle 来打乱这个数组,最后用 d3.slice 来取出前几张牌作为发牌结果。例如:
  1. // 导入 d3 库
  2. import * as d3 from "d3";
  3. // 创建一个扑克牌数组
  4. let suits = ["♠", "♥", "♦", "♣"];
  5. let ranks = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
  6. let cards = [];
  7. for (let suit of suits) {
  8.   for (let rank of ranks) {
  9.     cards.push(suit + rank);
  10.   }
  11. }
  12. // 打乱扑克牌数组
  13. d3.shuffle(cards);
  14. // 取出前五张牌作为发牌结果
  15. let hand = d3.slice(cards, 0, 5);
  16. // 打印出发牌结果
  17. console.log(hand);
复制代码
示例一:使用 d3.shuffle 来生成一个随机的颜色序列。我们可以先创建一个包含不同颜色名称和对应颜色代码的对象,然后用 d3.keys 和 d3.values 来提取出颜色名称和颜色代码的数组,再用 d3.shuffle 来打乱这两个数组,最后用 d3.permute 来根据打乱后的顺序重新组合成一个新的对象。例如:
  1. // 导入 d3 库
  2. import * as d3 from "d3";
  3. // 创建一个颜色对象
  4. let colors = {
  5.   red: "#ff0000",
  6.   orange: "#ffa500",
  7.   yellow: "#ffff00",
  8.   green: "#008000",
  9.   blue: "#0000ff",
  10.   violet: "#ee82ee"
  11. };
  12. // 提取出颜色名称和颜色代码的数组
  13. let names = d3.keys(colors);
  14. let codes = d3.values(colors);
  15. // 打乱两个数组的顺序
  16. d3.shuffle(names);
  17. d3.shuffle(codes);
  18. // 根据打乱后的顺序重新组合成一个新的对象
  19. let shuffled = {};
  20. for (let i = 0; i < names.length; i++) {
  21.   shuffled[names[i]] = codes[i];
  22. }
  23. // 打印出新的对象
  24. console.log(shuffled);
复制代码
observablehq-d3-shuffle
4.js中slice的用法

JavaScript 的 slice() 方法用于从数组中返回一个新的数组,该数组包含原数组中指定范围内的元素。
slice() 方法的语法如下:
  1. array.slice(start, end)
复制代码
其中:

  • array 是原数组。
  • start 是开始索引,默认为 0。
  • end 是结束索引,不提取该元素,默认为数组的长度,也就是提取之后的所有元素。
如果 end 是负数,则它表示从数组末尾开始向前计算的索引。
slice() 方法返回的数组是一个浅拷贝,它不会影响原数组。
slice() 方法的常见用法如下:

  • 从数组中返回指定范围内的元素:
  1. const arr = [1, 2, 3, 4, 5];
  2. const newArr = arr.slice(1, 3); // [2, 3]
复制代码

  • 从数组中返回所有元素:
  1. const arr = [1, 2, 3, 4, 5];
  2. const newArr = arr.slice(); // [1, 2, 3, 4, 5]
复制代码
相当于slice(0,5)

  • 从数组中返回最后一个元素:
  1. const arr = [1, 2, 3, 4, 5];
  2. const newArr = arr.slice(-1); // [5]
复制代码
这里相当于slice(-1,5),slice(4,5)

  • 从数组中返回第一个元素:
  1. const arr = [1, 2, 3, 4, 5];
  2. const newArr = arr.slice(0, 1); // [1]
复制代码

  • 从数组中返回除最后一个元素之外的所有元素:
  1. const arr = [1, 2, 3, 4, 5];
  2. const newArr = arr.slice(0, -1); // [1, 2, 3, 4]
复制代码

  • 从数组中返回除第一个元素之外的所有元素:
  1. const arr = [1, 2, 3, 4, 5];
  2. const newArr = arr.slice(1); // [2, 3, 4, 5]
复制代码
这里面是默认end为4
slice() 方法还可以与其他方法一起使用来实现更复杂的功能。例如,可以使用 slice() 方法和 filter() 方法来从数组中返回满足指定条件的元素。
  1. const arr = [1, 2, 3, 4, 5];
  2. const newArr = arr.filter(x => x % 2 === 0); // [2, 4]
复制代码
在上述示例中,filter() 方法用于过滤数组中的元素,只保留偶数。slice() 方法用于从过滤后的数组中返回指定范围内的元素。

来源:https://www.cnblogs.com/acrown/p/17737270.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具