【问题标题】:Javascript how to know if an array is subarray of anotherJavascript如何知道一个数组是否是另一个数组的子数组
【发布时间】:2010-12-10 00:46:28
【问题描述】:

如何以有效的方式在 javascript 中执行以下操作?

我按顺序计算了 7 个项目(项目 0、项目 1、项目 2...项目 6)。 就像计数 = [0,2,0,5,6,0,9];

有 3 个互斥组: 组 1:项目 0、项目 1、项目 2 组 2:项目 3、4、5 组 3:第 6 项

当且仅当组成员元素的计数器 >= 0 时,才认为组被选中。

现在我想知道选择了哪个组?

【问题讨论】:

  • 您可能想考虑一个更好的数据结构来表示它。你已经有什么代码了?你能告诉我们吗?
  • @kinopiko,我还没有开始编码。

标签: javascript arrays


【解决方案1】:

经过understack(OP)的澄清后,如果选择了[至少]一个元素,则选择了一个组。
这反过来又使问题的“互斥”部分模棱两可,因为提供的示例 (counts = [0,2,0,5,6,0,9]) 所有 3 个组都是选择...

永远不会少...
识别选择哪个组的问题可以通过依赖布尔表达式的 JavaScript 短路求值最佳解决

暂定的解决方案如下所示:

counts = [0,2,0,5,6,0,9];  // as stated an bad value for counts,
                           // if groups are to be mutually exclusive
if (counts[0] || counts[1] || counts[2])
{
   GroupSelected = 1;
}
else if (counts[3] || counts[4] || counts[5])
{
   GroupSelected = 2;
}
else if (counts[6] > 0)
{
   GroupSelected = 3;
}
else
{
   GroupSelected = -1;  //  none of the groups is selected !!!
}

注意:可能的优化将来自对要选择的给定元素的概率(相对于其他元素,在其组中)的“先验”知识,以及选择给定组的概率
有了这些知识,上面的sn-p就可以改写为首先测试最可能的组,然后在每个组内首先测试最可能的元素。

【讨论】:

  • @mjv:“当且仅当组成员元素的计数器 >= 0 并且至少一个元素计数器 > 0 时,才认为组被选中”。我明白了这里的想法。谢谢
  • 我想我找到了更好的解决方案。在计数数组中,将每个计数器设为 0 或 1。计数器 1 表示实际计数 >0。现在对组进行异或。所以组 1 将是 0000111 由前 3 个元素组成。
  • @understack。请在您澄清后查看我的编辑(关于构成选定组的内容)。您的 XOR 想法很好,但是... a) 据我所知,js 中唯一的 XOR 运算符是按位运算符,然后您需要将数组替换为整数,然后使用按位运算来设置/重置给定的“元素”。 b)您可能正在查看按位与而不是 XOR,以用作掩码 c)这正在稍微改变问题的性质(双关语),因为现在您的“数组”不传达数字信息,但只是一个布尔值。
  • @mjv:我想我给出了错误的样本计数器数组。你提供的信息真的很有帮助。谢谢。
【解决方案2】:

这是一个可以做你想做的事情的数据结构。

var DS = {
    Items: {},
    Groups: {},
    setItem: functon(index, item, group){
        this.Items[index] = item;
        if ( typeof this.Groups[group] === 'undefined' )
            this.Groups[group] = [index];
        else
            this.Groups[group].push(index);
    },
    isSelected: function(item) {
        return item >= 0;
    },
    isSelectedGroup: function(group) {
        var Group = this.Groups[group];
        for ( var i in Group ) {
            var Item = this.Items[i];
            if ( this.isSelected(Item) ) {
                return true;
            }
        }
    },
    getSelectedGroups: function(){
        var selected = [];
        for ( var group in this.Groups ) {
            var Group = this.Groups[group];
            if ( this.isSelectedGroup(Group) ) {
                selected.push(group);
            }
        }
        return selected;
    }
}

与您的项目一起使用:0,2,0,5,6,0,9。执行以下操作:

DS.setItem(0,0,1);
DS.setItem(1,2,1);
DS.setItem(2,0,1);
DS.setItem(3,5,2);
DS.setItem(4,6,2);
DS.setItem(5,0,2);
DS.setItem(6,9,3);

测试:

DS.isSelectedGroup(3);
// or to get all selected groups
DS.getSelectedGroups();

应该可以,如果没有,您应该能够弄清楚:)

【讨论】:

    【解决方案3】:

    使用 lodash 库,确定(子)数组的所有元素是否可以匹配另一个数组中的元素,

    function arrayMatchesSubarray(arr, subarr) {
      var filteredSubarray = _.filter(subarr, function(subarrelement) {
        return _.any(arr, function(arrelement){
          return arrelement === subarrelement;
        });
      });
      return _.isEqual(subarr, filteredSubarray);
    };
    

    结果:

    arrayContainsSubarray([1,2,3,4],[1,2]); // true
    arrayContainsSubarray([1,2,3,4],[5,6,1]); // false
    arrayContainsSubarray([1,2,3,4],[1,4,3]); // true
    

    【讨论】:

      猜你喜欢
      • 2016-12-13
      • 1970-01-01
      • 2012-08-29
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多