【问题标题】:Create an array and check against it创建一个数组并检查它
【发布时间】:2011-06-15 14:30:23
【问题描述】:

我不确定如何执行此操作,但我想要创建一个数组并能够向该数组添加新项目。由于项目应该是一个随机数,当创建一个新实例时,我希望它与数组的其余部分进行检查,并确保它生成的数字不在数组中。我将如何完成这样的事情?


我查看了 Šime Vidas 的答案,它似乎有效,但我试图将其缩短为

var arr = []; 

function add(a) {
var n =  ~~(Math.random() * 100);
for (var i = 0; i < a.length; i++) {
    if ( a[i] === n) { a.push(n) }
}

}

for (var i=0; i<5; i++){
    add(arr)
}

document.getElementById('output').innerHTML += arr;

我不明白为什么这不起作用。它的作用几乎相同,对吗?

【问题讨论】:

  • 删除的答案建议使用对象作为数据结构。为什么被删除了?对我来说似乎是个好主意。它避免了循环数组。
  • 我同意@Felix。只要原始顺序不重要并且不需要实际的 Array,使用 Object 将非常简单。

标签: javascript arrays random numbers


【解决方案1】:
var arr = []; 

function add(a) {
    var n =  ~~(Math.random() * 1000);
    !is(a, n) && a.push(n);
}

function is(a, n) {
    for (var i = 0; i < a.length; i++) {
        if ( a[i] === n ) { return true; }
    }
    return false;
}

add 函数创建一个 0 到 1000 之间的随机整数,并将其添加到数组中。
is 函数检查 n 数字是否在 a 数组中的某个位置。

演示: http://jsfiddle.net/kHhMp/2/

演示 2: http://jsfiddle.net/kHhMp/3/

(演示 2 显示只有在数组中没有数字时才会将其添加到数组中。)


顺便说一句

!is(a, n) && a.push(n);

是这个的简写形式:

if ( is(a, n) == false ) { a.push(n); }

仅当is(a, n) 返回 false 时,才会将数字添加到数组中。


更新

var arr = []; 

function add(a) {
    var n =  ~~(Math.random() * 1000),
        ok = true;

    for (var i = 0; i < a.length; i++) {
        if ( a[i] === n ) { ok = false; }
    }

    ok && a.push(n);
}

【讨论】:

  • 我无法判断 OP 是否希望该数字实际上是随机生成的,或者他是否在其他地方获取数字。此外,如果您稍后必须返回此代码,这将非常难以阅读。
  • @Jason 到底什么是难读的? is 函数非常简单明了。 add 函数使用 ~~&amp;&amp;,只有在你不理解它们的情况下(显然)才很难理解。如果您确实了解它们,我相信您可以很快阅读该功能。
  • @Jason 是的,我认为 OP 正在其他地方获取数字。我们会看看他说什么......
  • 不,你是对的,它们是随机数,(Math.random() * 1000) 是正确的。
  • ~~ 到底是干什么用的?
【解决方案2】:

如果你喜欢快速的代码并且你的数组中有很多项,你应该使用 Object 而不是 Array。

不要使用var my_array=[]; my_array.push(my_number),而是使用var my_object = {}; my_object[my_number] = true 在您的结构中添加项目。

使用这种方法,您可以使用if (my_object[my_number]) { /* already there */ } else { /* not there yet */ } 轻松检查新号码是否已经存在

完成后,您可以使用var keys = Object.keys(my_object) 将数字列表提取为一个数组,或者如果不可用,则使用var keys=[],i=0;for (keys[i++] in my_object); 或多或少。

【讨论】:

    【解决方案3】:

    您可以根据需要扩展内置的Array 对象。

    Array.prototype.pushUnique = function(value) {
      var len = this.length;
      for(var i = 0; i < len; i++) {
        if(this[i]===value) return;
      }
      this.push(value);
    }
    
    var uniques = new Array();
    uniques.pushUnique(1);
    uniques.pushUnique(2);
    uniques.pushUnique(1);
    // array will contain only 1 and 2
    

    【讨论】:

    • var ii 泄漏到全局范围内。
    【解决方案4】:

    最快、最跨浏览器的方法是使用循环遍历数组:

    var arr = [];
    
    function addNum(num) {
        for (i = 0, len = arr.length; i < len; i++) {
            if ( arr[i] === num ) { return false; }
        }
        arr.push(num);
    } 
    

    确保在运行循环之前获取数组的长度,这样长度属性就不会被不断检查。

    【讨论】:

      【解决方案5】:
      var array = []
      
      array[0] = 'Item'
      
      array[0] === undefined
      # returns false
      
      array[1] === undefined
      # returns true
      

      【讨论】:

      • in 在阵列上的性能如何?我可以想象一个对象会更好。
      • @Felix:不知道。我认为无论如何使用它可能是一个糟糕的主意——我认为它测试对象属性,而不仅仅是数组索引。
      • @Felix in 查找属性并将遍历原型链,它很慢并且可能存在错误。 @Paul 你应该使用严格等于=== 否则(array[0] = null) == undefined 将是true
      • @Ivo Wetzel:没错,不知何故,我认为in 在阵列上的工作方式会有所不同(但当然不是)。我想我想到了indexOf
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2016-11-03
      • 2013-11-22
      • 2016-05-08
      • 2020-01-11
      相关资源
      最近更新 更多