【问题标题】:Store count of integers in order using javascript使用javascript按顺序存储整数计数
【发布时间】:2016-03-10 21:22:10
【问题描述】:

我有如下字符串:

11222233344444445666

我想做的是在显示的时间后面输出数字: 112433475163

问题是,我希望它高效。我可以将它存储在一个对象中,如下所示:

1: { id: 1, displayed: 2},
2: { id: 2, displayed: 1},
3: { id: 3, displayed: 2}, 

等等

我可以访问这个对象并显示增量。

我的问题是,订单没有保证。我想按它们在字符串中的顺序存储键。如何实现对象中顺序的重要性?

【问题讨论】:

标签: javascript


【解决方案1】:

这是一个关于运行长度编码的提议,其中包含一个包含有关一个字符及其计数的信息的数组:

{
    "char": "1",
    "count": 2
},

var string = "11222233344444445666",
    array = function () {
        var r = [], o = {};
        string.split('').forEach(function (a, i, aa) {
            if (a !== aa[i - 1]) {
                o[a] = { char: a, count: 0 };
                r.push(o[a]);
            }
            o[a].count++;
        });
        return r;
    }(string);

document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');

【讨论】:

  • 此解决方案不适用于包含相同数字的非连续分组的字符串,例如“1211”
  • @itsananderson,是这个问题吗?问题是如何保留带有所需信息的订单,例如字符和计数。还是我错过了什么?
  • 我想它在技术上没有被列为要求,但作者最初的解决方案似乎是实现了一个更通用的字符出现计数器,这似乎暗示该字符串可能是一个随机集合数字。不过你可能是对的。
【解决方案2】:

for 循环的快速解决方案:

var str = "7771122229933344444445666",
    obj = {},
    len = str.length,
    val = null, 
    count_str = "",
    key = "";

for (var i = 0; i < len; i++) {
    val = str[i], key = 'k' + val;
    if (!obj[key]) {
       obj[key] = {'id': val, 'displayed': 1}; 
    } else {
        obj[key].displayed++;
    }
}
for (var p in obj) {
    count_str += obj[p]['id'] + obj[p]['displayed'];
}

console.log(count_str); // "7312249233475163"

【讨论】:

    【解决方案3】:

    因为你有这么小的一组不同的数字,我看不出你为什么不能使用数组(是的,如果你跳过值并且它变得稀疏,那么它在记忆方面不是超级理想的,但是对于这么小的子集它赢了对你的影响不足以担心它)。然后您可以使用 (number-1) 作为索引并根据需要增加该数字。

    var counts = [];
    var str = "11222233344444445666";
    for(var i in str){
        var index = parseInt(str[i])-1
        counts[index] = (counts[index]||0)+1;
    }
    for(var i in counts){
            var which = 1+parseInt(i);
        var count = counts[i];
        console.log("# of " + which +"'s: "+count);
    }
    

    https://jsfiddle.net/ga0fqpqn/

    注意:你不应该需要 parseInt(i)... 只是 +i 应该可以工作,但我认为 jsfiddle 有一个错误,它默认 i 像字符串一样处理。

    【讨论】:

    • 1+i不起作用的原因是因为它被视为concat而不是add,所以结果例如是“11”。
    • 是的,我知道这就是正在发生的事情,但是当我收到一个整数时,我只是习惯于不必将其断言为 int。可能只是以前从未注意到
    【解决方案4】:

    您可以存储一个具有数字顺序的附加数组,仅当对象尚不包含给定数字时才附加到该数组。完成计数后,遍历该数组并从查找字典中输出数字和计数。

    var chars = "1234576123452345".split("");
    var order = [];
    var hash = {};
    chars.forEach(function(char) {
      if (!hash[char]) {
        hash[char] = 1;
        order.push(char);
      } else {
        hash[char]++;
      }
    });
    
    console.log(order.map(function(char) {
      return char + hash[char];
    }).join(""));
    
    // "12233343537161"
    

    【讨论】:

    • 我不知道为什么这么快就被否决了。虽然我可以看到一个问题是,如果收到的第一个值不是按照您制作的一系列哈希的顺序排列的,那么您将得到未排序的值。例如尝试使用 var chars = "1234765123452345";所有字符串也是字符数组。没必要这么分裂
    • 请求是按照它们在字符串中出现的顺序输出字符,而不是排序,所以我认为我的解决方案是正确的。此外,字符串没有 forEach 方法,因此如果您想避免使用 for 循环,则必须拆分它。
    • 我暗示你应该使用 for 循环,因为性能原因 (jsperf.com/for-vs-foreach/66) :P 无论哪种方式。我一定是误解了这个问题。
    • 如果您正在优化绝对最快的解决方案,for 循环是正确的选择,但对于相当小的字符串,值得使用 forEach 来提高代码清晰度。
    • 好点。我猜我不太习惯 JavaScript 风格的编码。但是,是的,速度性能是我习惯于被要求考虑的事情。我会尽量记住这一点,因为我将来会在 JS 中开发,这比 for 循环更受欢迎
    猜你喜欢
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多