【问题标题】:JS: Array shuffling, not string shufflingJS:数组改组,而不是字符串改组
【发布时间】:2015-07-13 19:38:55
【问题描述】:

我正在尝试使用 JS 对字符串数组进行洗牌。我硬编码了三组字符。从每组中随机选择 3 个字符,然后连接起来。所以串联的字符串是 3 个字母,后跟 3 个数字,后跟 3 个符号。我想打乱这个连接的字符串,以便它们的顺序是随机的。

我已经检查了How to randomize (shuffle) a JavaScript array?,我的算法和代码基本上与第二种解决方案相匹配,除了我在一个更大的函数(而不是它自己的函数)中有随机循环。也许我应该将改组添加到它自己的函数中并在更大的函数中调用它,但我认为这仍然会给我同样的结果。

函数的“改组部分”实际上并不是改组。当我使用 console.log(temp) 和 console.log(tp[rnd]) 调试它时,会显示正确的值。基本上,该函数正在返回我想要洗牌的未洗牌字符串。

var letterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var numberSet = "0123456789";
var symbolSet = "~!@#$%^&*()-_+=><";

this.generatePassword = function() {
        var rl = "";
        var rn = "";
        var rs = "";
        var tp = "";

        // 3 random letters
        for(var i = 0; i < 3; i++) {
            var rnd = Math.floor((Math.random() * 52));
            rl += letterSet[rnd];
        }

        // 3 random numbers
        for(var i = 0; i < 3; i++) {
            var rnd = Math.floor((Math.random() * 10));
            rn += numberSet[rnd];
        }

        // 3 random symbols
        for(var i = 0; i < 3; i++) {
            var rnd = Math.floor((Math.random() * 17));
            rs += symbolSet[rnd];
        }

        // String concatenation
        tp = rl + rn + rs;

        // Shuffling part
        for(var i = 0; i < tp.length; i++) {
            var rnd = Math.floor(Math.random() * tp.length);
            var temp = tp[i];
            tp[i] = tp[rnd];
            tp[rnd] = temp;
        }

        return tp;
    }();

我不明白出了什么问题。

【问题讨论】:

标签: javascript random shuffle


【解决方案1】:

你的洗牌有点不对劲,我看了this,它使用一个数组来洗牌。

// String concatenation
tp = rl + rn + rs;
tp=tp.split('');

// Shuffling part
for(var i = 0; i < tp.length; i++) {
   var rnd = Math.floor(Math.random() * tp.length);
   var temp = tp[i];
   tp[i] = tp[rnd];
   tp[rnd] = temp;
}
tp=tp.join("");

【讨论】:

  • 成功了。为什么需要'split()'函数?
  • split 函数从字符串中创建一个数组,因此操作是使用数组而不是字符串,这是不可能的。
  • @daChi splitjoin 部分是必需的,因为 javascript 中的字符串是不可变的(因为它们实际上是值),而数组则不是。
  • 哦,所以当我认为我正在洗牌一个数组时,我正试图洗牌一个字符串。明白了。
  • 有一些方法可以在不将其转换为数组的情况下操作字符串。请看下面我的回答。 @doldt
【解决方案2】:

当您执行分配 tp[i] = tp[rnd]tp[rnd] = temp 时,它不会更改 tp 的值,因为字符串是不可变的。可以使用String 上的方法来操作字符串和替换值。将这两个分配更改为以下内容:

for (var i = 0; i < tp.length; i++) {
    var rnd = Math.floor(Math.random() * tp.length);
    var temp = tp[i];
    tp = tp.replace(tp.substr(i, 1), tp[rnd]);
    tp = tp.replace(tp.substr(rnd, 1), temp);
}

【讨论】:

  • 值得注意的是,从技术上讲,在这种情况下,您也不会改变字符串:创建了一个新字符串,将其分配给 tp 变量而不是旧的。
  • 这也很有趣......你说哪种方式更好?将字符串转换为数组,然后再转换回字符串,还是仅对字符串本身进行字符串操作?
猜你喜欢
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2013-09-19
  • 2010-10-04
相关资源
最近更新 更多