【问题标题】:Pull array values associated with bitmask拉取与位掩码关联的数组值
【发布时间】:2016-06-30 02:10:27
【问题描述】:

我有一个简单的位掩码,3"011" in base 2)表示我应该提取 array[0]array[1] 而不是 array[2]

什么是有效的方法?

最终,我生成了一个新数组,其中的值传递了 .filter

类似这样的:

var bitmask = 37, // "100101"
    array = ["a", "b", "c", "d", "e", "f"];

var array2 = array.filter((value, index) => {
    // do something with bitmask and index to return true
});

// array2 should be ["a", "c", "f"];

【问题讨论】:

  • 这不是位掩码,它是一个字符串。
  • 你是对的,但你知道我的意思,它实际上是一个数字
  • 实际上将其覆盖为二进制然后一个字符串会很有用,这样您就可以遍历它并检查"1"
  • 问题是,我正在从 000001 迭代到 111111,以便我可以获得所有可能的选择来填充最多 6 个插槽,不确定我是否要循环遍历字符串以及数组
  • 不应该返回['a', 'd', 'f']吗?或者我把你的问题弄错了。如果位掩码长度高于数组长度怎么办?

标签: javascript algorithm bitmask


【解决方案1】:

扩展您的原始示例,您可以这样做:

var bitmask = 37, // "100101"
    array = ["a", "b", "c", "d", "e", "f"];

var array2 = array.filter((value, index) => {
    // do something with bitmask and index to return true
    return bitmask & (1 << index);
});

// array2 should be ["a", "c", "f"];
console.log(array2);

【讨论】:

  • 生病了,这非常完美,是的,我打算这样做 (bitmask &gt;&gt; index) % 2 但这更干净
【解决方案2】:

var bitmask = 5, idx=0;
// Loop till bitmask reach 0, works when bitmask >= 0
// If you want to sure instead of implicit type converting (from number to boolean)
// Just change it to while(bitmask >= 0)
while(bitmask){
   // If the rightmost bit is 1, take the array[index]
   if(bitmask & 1) console.log("take arr["+idx+"]");
   // Shift right by 1 bit, say 5 = 101,  this will make the number become 2 = 10
   bitmask>>=1; 
   // Increase the index 
   idx++;
}

使用您自己的示例,代码如下:

var bitmask = 37, // "100101"
    array = ["a", "b", "c", "d", "e", "f"],
    idx = 0;
var array2 = [];
while(bitmask){
   if(bitmask & 1) array2.push(array[idx]);
   bitmask>>=1; 
   idx++;
}

只需使用一些位操作来循环它。由于它是一点点循环的,我认为它是你能得到的最快的

【讨论】:

  • @neaumusic 在代码中添加一些cmets,请看是否够清楚。由于它只是简单地将位掩码用作数字,无需将其转换为字符串,无需任何字符串操作,只需循环遍历位掩码的所有二进制位,我认为这是最快的方式
【解决方案3】:

执行此操作的一种方法是将您的数字转换为二进制字符串,然后检查位掩码的索引是否在您的过滤器内为"1"

    var bitmask = (37).toString(2), // "100101"
        array = ["a", "b", "c", "d", "e", "f"];
    
    var array2 = array.filter((value, index) => {
        if(bitmask[index] == "1") return value;
    });
    
    console.log(array2);

【讨论】:

  • @neaumusic 刚刚注意到您在问题中发表了评论,抱歉,我认为这是一个错字。在这种情况下,您只需要反转字符串:var bitmask = (37 &gt;&gt;&gt; 0).toString(2).split("").reverse().join("").
  • 一切都很好,这些都是正确答案,我只是想确定哪个更有效,实际上我认为顺序并不重要,因为我得到了所有排列方式
  • @neaumusic 可能是另一个答案,它是使用位运算符的基本 while 循环。
  • 我看到如果37 &gt;&gt; index 是奇数,那么它是匹配的,因为存在 1 的数字
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多