简体   繁体   English

使用Javascript搜索数组中的项目

[英]Search for item in array with Javascript

I am trying to add some code where the user clicks a button and the code generates 3 numbers (none repeating, so 245 is OK but 122 and 121 is not) and display them onscreen, one each second. 我试图在用户单击按钮的地方添加一些代码,该代码生成3个数字(没有重复,因此245可以,但122和121则不可以)并在屏幕上每秒显示一次。 To ensure there are no repeats, I am using an array: var usedNums = []; 为了确保没有重复,我使用了一个数组: var usedNums = []; . Then, I create the number ( digit = Math.random() ) and check if it is already in the array, and if it's not, add it, like this: 然后,我创建一个数字( digit = Math.random() ),并检查它是否已经在数组中,如果不是,则添加它,如下所示:

if ($.inArray(digit, usedNums) !== -1) {
        newNums();
    } else {
        usedNums.push(digit);
        $('#memDigit').html(digit);

}

The first few times, it works, but when I click it for the 10th time, I get the Uncaught RangeError: Maximum call stack size exceeded error. 最初的几次,它都有效,但是当我第十次单击它时,我收到了Uncaught RangeError: Maximum call stack size exceeded错误。 Help! 救命!

Here's the full code: 这是完整的代码:

var usedNums = [];
var digit;
var amount = 3;

function newNums() {
    digit = Math.floor(Math.random() * 10);
    if ($.inArray(digit, usedNums) !== -1) {
        newNums();
    } else {
        usedNums.push(digit);
        $('#memDigit').html(digit);

    }

}

function createNums() {
    for (var i; i < amount; i++) {
        setTimeout(newNums, 1000);
    }
}

//$(document).ready(createNums);

我认为您应该在每个数字生成完成后清空/重新初始化usedNums数组。

If IE <= 10 is not a concern, you may want to take advantage of crypto.getRandomValues to do this in one shot instead. 如果IE <= 10 crypto.getRandomValues ,则您可能希望利用crypto.getRandomValues完成此操作。

The getRandomValues method fills a TypedArray with a series of random values in the range supported by that array type. getRandomValues方法使用在该数组类型支持的范围内的一系列随机值填充TypedArray If we ask for 10 of these vales, we now have, in effect, a hash of the numbers 0-9 (that is, the indices of the array) pre-associated with random values for sorting by (the values). 如果我们要求这些值中的10个,则实际上实际上是一个数字0-9(即数组的索引)的散列,该散列预先与随机值相关联以用于按(值)排序。 The result will be both more random and — unlike the 'already seen this value, try again' pattern — it should run in constant time. 结果将更加随机,并且-与“已经看到此值,请重试”模式不同-它应在恒定时间内运行。

ES6: ES6:

const nums = [ ...crypto.getRandomValues(new Int16Array(10)) ]
  .map((sortVal, num) => [ sortVal, num ])
  .sort(([ a ], [ b ]) => a < b ? -1 : Number(a > b))
  .map(([ , num ]) => num)
  .slice(0, 3);

ES5: ES5:

var nums = [].slice.call(crypto.getRandomValues(new Int16Array(10)))
  .map(function(sortVal, num) { return [ sortVal, num ]; })
  .sort(function(a, b) { return a[0] < b[0] ? -1 : Number(a[0] > b[0]); })
  .map(function(pair) { return pair[1]; })
  .slice(0, 3);

Breakdown: 分解:

  • new Int16Array(10) creates an empty TypedArray of length 10 new Int16Array(10)创建一个长度为10的空TypedArray
  • crypto.getRandomValues(...) fills that array with random values crypto.getRandomValues(...)使用随机值填充该数组
  • We convert the result to a regular array 我们将结果转换为常规数组
  • We map that to [ randomVal, index ] tuples 我们将其映射到[randomVal,index]元组
  • We sort that by the random value (remembering to coerce to Number explicitly, to cover the Safari sort implementation bug) 我们通过随机值对其进行排序(记住明确强制转换为Number,以涵盖Safari sort实现错误)
  • We map down to just the index — ie, a number from 0-9 我们只映射到索引,即0-9之间的数字
  • We grab just the first three values 我们只获取前三个值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM