【问题标题】:Find duplicates in array JavaScript在数组 JavaScript 中查找重复项
【发布时间】:2019-01-02 20:31:34
【问题描述】:

所以我正在开发一个基于 JavaScript 的简单网络游戏。目标是猜测 X 位随机数。这意味着随机数可以是 4、5 位数字,最多可以是您想要的任何数字。您实际上可以在 www.juegodescifralo.com 上玩游戏(这是西班牙语,对此感到抱歉)。

用户输入一个以数组形式存储的数字。随机数也作为数组生成。两个数组中的单个数字都可以重复。

存在三种可能的“值/数字”:“好”的数字是您选择的与随机数组中的数字位置相同的数字。比如:

随机数组为:1457

用户输入为:6851

数字 5 是一个“好”的数字,因为它位于相同的位置。然后是第二种“值”,即“常规”。这意味着它们在随机数内,但不在同一位置。在此示例中,数字 1 将是“常规”值。第三种是“坏”的,甚至不在随机数组中。

我开发的功能如下:

function checkNumbers(randomArray, myArray, good, regular, bad) {
    for (var x = 0; x < randomArray.length; x++) {
        var posRepetido = randomArray.indexOf(myArray[x]); //Is current number inside random array?

        if (posRepetido == -1) { //It's not inside
            console.log("number " + myArray[x] + "is not inside");
            bad++;

        } else { //It's inside

            regular++;

            if (myArray[x] == randomArray[x]) { //If it's the same number...
                console.log("number " + myArray[x] + "is in the correct position");

                good++;
                regular--;
            } else { //If it's not the same number

                if (randomArray[posRepetido] != myArray[posRepetido]) {
                    console.log("number " + myArray[x] + "is inside but not in the same position");

                } else {
                    console.log("number " + myArray[x] + "is not inside");

                }
            }
        }
    }

    var obj = { //Return object for accessing later, to show feedback to the user.
        good: good,
        regular: regular,
        bad: bad
    };

    return obj;
}

代码有点错误。当随机数组中有重复项,其中一个被标记为好,那么另一个(即使它存在于用户输入中)将被设置为坏,而不是应有的规则。

事情变得更加复杂,因为您应该能够与任意数量的数字对战。所以我应该能够毫无“问题”地猜出一个 20 位数字。

您可以在 www.juegodescifralo.com 上自己玩

我该怎么办?任何想法如何更轻松地访问数组数据?非常感谢!

【问题讨论】:

    标签: javascript arrays loops


    【解决方案1】:

    这应该可行。

    function guessNumber (numUser, numRandom) {
        if (typeof numUser == 'number') {
            numUser = numUser.toString().split('');
        }
        if (typeof numRandom == 'number') {
            numRandom = numRandom.toString().split('');
        }
     
        if (typeof numRandom != 'object' || typeof numUser != 'object') {
            return false;
        }
     
        if (numRandom == numUser) {
            return true;
        }
     
        var numRegular = {},
            numBuenos = {},
            numMalos = {},
        numRepeat = {};
     
     
        for(var i  = 0; i < numRandom.length; i++) {
          if (!numRepeat[numRandom[i]]) {
            numRepeat[numRandom[i]] = 0;
        }
          numRegular[numRandom[i]] = 0;
          numRepeat[numRandom[i]]++;
      }
     
     
        for (var i  = 0; i < numUser.length; i++) {
            if (numUser[i] == numRandom[i]) {
                numBuenos[numUser[i]] = numUser[i];
            }else if ($.inArray(numUser[i], numRandom)) {
          if (!numRegular[numUser[i]]) {
            numRegular[numUser[i]] = 0;
          }
          if (numRegular[numUser[i]] < numRepeat[numUser[i]]) {
              numRegular[numUser[i]]++;
          } else {
                    numMalos[numUser[i]] = numUser[i];
          }
            } else {
                numMalos[numUser[i]] = numUser[i];
            }
        }
     
     
        return {
            regular: Object.values(numRegular).reduce((a, b) => a + b),
            buenos: Object.keys(numBuenos).length,
            malos: Object.keys(numMalos).length
        };
     
    }
     
    console.log(guessNumber(8365, 8512));
    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 能否请您解释一下您所做的更改以及问题所在?
    【解决方案2】:

    我认为像这样循环两次更容易

    function checkNumbers(randomArray, guessArray) {
      var clone = randomArray.slice(0);
      var good = 0;
      var regular = 0;
      var bad  = 0;
      var visited = [];
    
      guessArray.forEach(function(guess, index) {
        if (guess === clone[index]) { // the guess is in right position
          good++;
          clone[index] = "x"; // strike it out so it cannot be used later
          visited.push(index);
        } else if (clone.indexOf(guess) === -1) {
          bad++;
          visited.push(index);
        }
      });
      guessArray.forEach(function(guess, index) {
        if (!visited.includes(index)) {
          var match = clone.indexOf(guess);
          if (match !== -1) {
            regular++;
            clone[match] = "x"; // strike it out so it cannot be used later
          }
        }
      });
    
      return {
        good: good,
        bad: bad,
        regular: regular
      }
    }
    

    第一个循环是检查好坏。并删除它的价值,因此它不能再次使用。

    第二个循环检查常规并删除它使用的值,因此它不能再次使用。

    【讨论】:

    • 理解代码对我来说有点困难......但是,在尝试提供给“CertainPerformance”的示例时(随机 [8, 1, 8, 8, 5] 用户 [8, 5, 1, 1, 1]) 函数以某种方式返回 1 好 1 正常和 0 坏。此外,被删除的数字成为随机 arr ([x, x, 8, 8, 5]) 的前两个。为什么会是这样的结果?非常感谢!
    • 对不起,这是可能代码中的一个错误 :-( 我已经更新了我的答案
    • 现在,给定我第一个评论中的示例(5 位数字),它返回 1 好,0 坏,2 常规。您之前给出的示例也发生了类似的情况: [4, 1, 1, 4] 和 [1, 4, 1, 1] 也返回 1 个好、0 个坏、2 个常规。我真的不知道原因......而且不知何故,坏的没有被记录,什么时候应该记录,因为重复的每个额外数字都应该是一个“坏”数字。提前谢谢你!
    • 对不起,我可能误解了逻辑。使用 [4, 1, 1, 4] 和 user = [1, 4, 1, 1],我们有 1 个好用户 [x,x,1,x] 和 2 个常规用户 [1, 4, x, x]
    • 好吧,看来我没有正确解释自己,或者我不明白你的意思哈哈。你试过玩游戏吗?即使它是西班牙语,也许你明白了。 www.juegodecifralo.com
    【解决方案3】:

    indexOf-1 的比较和myArray[x] 的检查相比,使用includes 和数组方法(如forEach)可能会容易得多,以实现更好的抽象。您真正需要的是ifelse ifelse。例如:

    function checkNumbers(randomArray, userArray, good=0, regular=0, bad=0) {
      userArray.forEach((guess, i) => {
        if (guess === randomArray[i]) good++;
        else if (randomArray.includes(guess)) regular++;
        else bad++;
      });
      return { good, regular, bad };
    }
    
    
    
    // 4 good
    console.log(checkNumbers(
      '1234'.split(''),
      '1234'.split(''),
    ));
    // 4 good, 2 bad
    console.log(checkNumbers(
      '1234'.split(''),
      '123456'.split(''),
    ));
    // 4 good, 2 regular
    console.log(checkNumbers(
      '1234'.split(''),
      '123412'.split(''),
    ));
    // all regular:
    console.log(checkNumbers(
      '123456789123456789'.split(''),
      '912345678912345678'.split(''),
    ));

    【讨论】:

    • 这是一个非常好的进步。但是,当与我的代码比较时,它在以下示例中返回相同:随机数组:81885 用户数组:85111 返回:1 好,4 正常。即使它确实是 1 好 2 常规和 2 坏,因为在用户输入中有两个额外的。这确实是问题所在,能够区分重复的“额外”字符。这让我很头疼。我不知道 JavaScript 中的“forEach”。谢谢!我会继续研究,看看能不能找到解决办法。
    猜你喜欢
    • 2013-07-31
    • 2014-08-08
    • 2014-01-26
    • 2018-05-16
    相关资源
    最近更新 更多