简体   繁体   English

使用随机生成的值检查数组中的重复项

[英]Check for duplicates in array with randomly generated values

I'm working on exercism question and am stuck on one of the jasmine-node based tests, which says that I should be able to generate 10000 random names without any clashes (eg 2 randomly generated names match). 我正在研究运动问题,并停留在一个基于茉莉花节点的测试中,该测试表明我应该能够生成10000个随机名称而不会发生冲突(例如2个随机生成的名称匹配)。 This is the test: 这是测试:

it('there can be lots of robots with different names each', function() {

    var i,
    numRobots = 10000,
    usedNames = {};

    for (i = 0; i < numRobots; i++) {
      var newRobot = new Robot();
      usedNames[newRobot.name] = true;
    }

    expect(Object.keys(usedNames).length).toEqual(numRobots);

});

What I think I need to do is: 认为我需要做的是:

  1. Create an array to hold all the names (robotNames), 创建一个数组来保存所有名称(robotNames),
  2. Each time a name is generated, check if it exists in the array, 每次生成名称时,请检查名称是否存在于数组中,
  3. If it does, generate another name, 如果是这样,请生成另一个名称,
  4. If it doesn't, add it to the array. 如果不是,则将其添加到数组中。

And here is my code so far... 到目前为止,这是我的代码...

"use strict";

var robotNames = [];
var name;

var Robot = function() {
    this.name = this.generateName();
};

Robot.prototype.generateName = function() {

    var letters = "";
    var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    var numbers = "";
    var digits = "0123456789";

    // generate random characters for robot name...

    for( var i=0; i < 2; i++ ) {
        letters += alphabet.charAt(Math.floor(Math.random() *    alphabet.length));
    };

    for( var i=0; i < 3; i++ ) {
        numbers += digits.charAt(Math.floor(Math.random() * digits.length));
    };

    name = letters+numbers;

    // Loop through array to check for duplicates

    for(var i = 0; i < robotNames.length; i++) {
        if (name == robotNames[i]) {
            this.generateName();
            return;
        } else {
            robotNames.push(name);
        }
    }

    return name;
};

Robot.prototype.reset = function() {
     this.name = this.generateName();
};

module.exports = Robot;

The test fails with an error message: "Expected 9924 to equal 10000." 测试失败,并显示错误消息:“预期9924等于10000”。

The '9924' number is slightly different each time I run the test. 每次运行测试时,“ 9924”数字都会略有不同。 I'm thinking this means the generateName function is eventually generating 2 matching random names. 我认为这意味着generateName函数最终会生成2个匹配的随机名称。 It seems as though my loop for checking duplicates is not being run and I'm not sure why. 似乎我的检查重复项的循环未在运行,我不确定为什么。

I have tried a couple of different versions of the loop but with no success. 我尝试了几个不同版本的循环,但没有成功。 So my questions is a) is my approach correct and there is something wrong with the syntax of my loop? 所以我的问题是:a)我的方法正确吗,循环的语法有问题? or b) have I got the wrong idea about how to check for duplicates here? 或b)我对在此处检查重复项是否有错误的想法?

Any pointers appreciated, thanks. 任何指针表示赞赏,谢谢。

The problem is in this bit: 问题出在这一点:

for(var i = 0; i < robotNames.length; i++) {
    if (name == robotNames[i]) {
        this.generateName();
        return;
    } else {
        robotNames.push(name);
    }
}

...you probably only want to push your name if NONE of the names fail to match. ...您可能只想在没有一个名称不匹配的情况下输入您的名字。 Here you're adding it to the list as soon as you find ONE that doesn't match. 在这里,只要找到不匹配的一个,就将其添加到列表中。 You want something more like: 您想要更多类似的东西:

for(var i = 0; i < robotNames.length; i++) {
    if (name == robotNames[i]) {
        return this.generateName();
    }
}
robotNames.push(name);

(actually, combined with the fact that you weren't even returning the recursive call to this.generateName(), I'm not sure how your program could work...) (实际上,结合您甚至没有将递归调用返回给this.generateName()的事实,我不确定您的程序如何工作...)

Find a library with an implementation for Sets. 查找具有Sets实现的库。 Collections.js is a good example. Collections.js是一个很好的例子。

One property of a set is that it doesn't have duplicates. 集合的一个属性是它没有重复项。 So when you add a value to a set it will look for a duplicate and then add the value if no duplicate exists. 因此,当您向集合中添加值时,它将查找重复项,如果不存在重复项,则将其添加。

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

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