【问题标题】:Understanding the use of Math.floor when randomly accessing an array了解随机访问数组时 Math.floor 的使用
【发布时间】:2017-09-02 04:24:36
【问题描述】:

我使用在此站点上找到的代码来访问字符串值数组。我更改了变量名,但除此之外,代码保持不变。

var rand = array[Math.floor(Math.random() * array.length)];

它有效,据我了解,(Math.random() * array.length) 是本身生成随机数的区域,那么为什么需要Math.floor?我显然不明白这里很明显的东西。

【问题讨论】:

  • Math.random 返回一个浮点数,数组元素索引实际上是整数。 Math.floor 将浮点数向下舍入到最接近的整数。

标签: javascript arrays math random floor


【解决方案1】:

Math.floor 返回一个整数,而Math.random() 将返回一个介于 0 和 1 之间的浮点数。

要访问数组中的项目,例如rand[0],您需要有一个整数。您无法使用 rand[1.43] 访问数组中的项目。

那一小行代码将通过生成一个从零到数组长度的随机浮点数来访问数组中的一个随机项,然后用Math.floor将它四舍五入到最接近的整数

【讨论】:

  • 所以,Math.random() 可能产生 0.7,乘以 array.length(在我的情况下为 3),将得到 2.1 - Math.floor 将变为 2,这意味着第三个数组值将被访问。对吗?
  • 正确!这就是它的基本原理。
  • 谢谢哥们。所有的回复都很棒,超出了我的要求,但是您以一种很容易理解的方式解释了它:)
【解决方案2】:

因为没有小数数组元素

const array = [123, 456];
console.log(array[0.5]);

上面的代码打印undefined,因为没有0.5 元素。有一个0 元素和一个1 元素但没有0.5 个元素

所以,要选择带有Math.random() 的随机元素,它返回一个介于 0 和 1 之间(但不是 1)的数字,您必须将其转换为整数。

JavaScript 数组与大多数其他语言中的数组不同。它们实际上更像是增强对象。它们就像数组一样,您可以获取长度 (array.length) 并调用诸如 push、pop、concat、shift、unshift 之类的东西,但您也可以添加属性

array = [4, 5, 6];
array["foo"] = "bar"
console.log(Object.keys(array));

打印

[
  "0",
  "1",
  "2",
  "foo"
]

这就解释了为什么没有Math.floorMath.random 会失败。从 JavaScript 的语义角度来看,数组只是一个具有名为 0、1、2、3 等属性的对象。当然,这不是 JavaScript 所做的,因为以这种方式实现数组会太慢,但对于大多数部分数组的行为就像它们实际上只是一个具有名为“0”、“1”、“2”的属性的对象,并且具有名为“0.00012”等的属性是完全有效的。

注意,这样做实际上会更快

const rand = array[Math.random() * array.length | 0];

| 0 是 0 的二进制,JavaScript 规范有效地表示结果在 | 发生之前转换为整数。请注意,| 0Math.floor 不同。 | 0 向 0 舍入,而 Math.floor 向下舍入。

         | 0   Math.floor         
------+------+------------
  2.5 |   2  |   2
  1.5 |   1  |   1
  0.5 |   0  |   0
 -0.5 |   0  |  -1
 -1.5 |  =1  |  -2
 -2.5 |  -2  |  -3

【讨论】:

  • 从来不知道| 0。谢谢!
【解决方案3】:

var array = [10,6,2,11,0];
console.log(array[3]); // output = 11

//Math.random() generates random floating point numbers from 0(inclusive) to 1(exclusive).
//Math.random() * array.length will generate all random numbers from 0 to array.length(exclusive)

var randomNumber = Math.random();
console.log("randomNumber = " + randomNumber); // Say, output = 0.8604458676303853
console.log("randomNumber * array.length = " + randomNumber * array.length); // Say, output = 4.3022293381519265

//To access any element in the array you will need indices starting from 0 to array.length(exclusive)

//var rand = array[randomNumber * array.length];
//Will give error as array cannot access a floating point index

console.log("Math.floor(randomNumber * array.length) = " + Math.floor(randomNumber * array.length)); // Say, output = 4

//Finally,
var rand = array[Math.floor(Math.random() * array.length)];
console.log("rand = ", rand);

floor函数会为你做以下事情。

  1. 它将首先对浮点数进行四舍五入,使其成为可以访问的有效索引。

总的来说,Math.floor(Math.random() * array.length) 会注意最大索引值始终是 array.length - 1

原因是我们得到的最大数总是略小于array.length)。
因此,即使 Math.random() 生成 0.999 并将其与 array.length = 5 相乘。
因此,0.999 * 5 = 4.995 和 (4.995) 的下限 = 4。满足约束:)

【讨论】:

  • 对于您的第 2 点,Math.floor 不会做第二件事,Math.random 通过不返回 1 来做到这一点。所有 floor 所做的都是向下舍入。为了使第 1 点清晰,地板不会“圆”它的地板。要四舍五入,您可以致电Math.round。另一种说法是 Math.ceil 向上取整,Math.floor 向下取整,Math.round 取整。
  • 感谢您的指正。心里有数,一不小心写错了。
猜你喜欢
  • 2013-03-27
  • 1970-01-01
  • 2014-05-07
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多