删除子数组包含常用元素

时间:2017-05-16 14:57:39

标签: javascript arrays

作为标题,如果输入为[[1,2],[3,4],[1,3],[5,6],[6,5]],则输出应为[[1, 2,3,4],[5,6]]。 这在递归部分是错误的。在我的代码中,运行之后,我会得到[[1,2,3],[1,3,4],[5,6]],这意味着我需要再次合并,但我感到很困惑如何继续代码,直到没有子数组包含公共元素。

这是我的代码

function need_merge_or_not(arr)
{
  for (var i = 0; i <= arr.length-1; i++) {
      for (var j = i+1; j <= arr.length-1; j++) {
        var arr_new = arr[i].concat(arr[j]);
        //remove deplicates
        var arr_merge = arr_new.filter(function (item, pos) {return arr_new.indexOf(item) == pos});
        if (arr_merge.length < arr_new.length) {
          return true;
        }
      }
  }
  return false;
}


function merge(arr)
{
  if (arr.length >= 2) {
    for (var i = 0; i <= arr.length-1; i++) {
      for (var j = i+1; j <= arr.length-1; j++) {
        var arr_new = arr[i].concat(arr[j]);
        var arr_merge = arr_new.filter(function (item, pos) {return arr_new.indexOf(item) == pos});
        if (arr_merge.length < arr_new.length) {
          arr.splice(arr.indexOf(arr[i]), 1);
          arr.splice(arr.indexOf(arr[j]),1);
          arr.push(arr_merge);
        }
      }
        if (need_merge_or_not(arr)) {
          return merge(arr);
        }
    }
  }
  return arr;
}

2 个答案:

答案 0 :(得分:0)

您可以使用两个哈希表,一个用于项目及其groups,然后用于结果sets

基本上,算法为同一组生成一个具有属性和数组的对象,因为它允许在分配新数组时保留对象引用。

主要部分是迭代外部数组,然后是内部数组并检查内部,如果是第一项,则检查哈希表是否存在,如果不存在,则生成一个带有values属性且为空的新对象数组作为值。同时将实际对象分配给sets,并将项目作为键。

在下一步中,再次检查哈希表,如果不存在,则分配第一个元素的对象。

要仅维护唯一值,请进行检查,如果该项不存在,则将该项推送到哈希表的values数组。

然后通过检查第一项的对象是否不等于实际项的对象来跟随连接数组的部分。如果是这样,它会从sets中删除实际项目值第一项中的键,并将实际项目的数组连接到第一项的对象值。然后将值对象分配给实际项目的对象。

稍后sets通过迭代sets对象来绑定到结果集,并将values属性作为值。

var array = [[1, 2], [3, 4], [1, 3], [5, 6], [6, 5]],
    groups = {},
    sets = {},
    result;
    
array.forEach(function (a) {
    a.forEach(function (b, i, bb) {
        if (i === 0 && !groups[b]) {
            groups[b] = { values: [] };
            sets[b] = groups[b];
        }
        if (!groups[b]) {
            groups[b] = groups[bb[0]];
        }
        if (groups[b].values.indexOf(b) === -1) {
            groups[b].values.push(b);
        }
        if (groups[bb[0]] !== groups[b]) {
            delete sets[groups[b].values[0]];
            groups[bb[0]].values = groups[bb[0]].values.concat(groups[b].values);
            groups[b].values = groups[bb[0]].values;                    
        }
    });    
});

result = Object.keys(sets).map(function (k) {
    return sets[k].values;
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

我明白了。这是代码:

function merge(arr){
  var input = [];
  for(var i = 0; i < arr.length; i++){
    input.push(arr[i]);
  } 
  if (arr.length >= 2) {
    for (var i = 0; i < arr.length; i++) {
      for (var j = i+1; j < arr.length; j++) {
        var arr_new = arr[i].concat(arr[j]);
        //remove duplicates
        var arr_merge = arr_new.filter(function (item, pos) {return arr_new.indexOf(item) == pos});
        if (arr_merge.length < arr_new.length) {
          arr.splice(arr.indexOf(arr[i]), 1, arr_merge);
          arr.splice(arr.indexOf(arr[j]),1);
          j--;
        }
      }   
    }
    if (!arraysEqual(input, arr)) {merge(arr)};
  }
  return arr;
  //Input:[[1,2], [3,4], [1,3], [5,6], [6,5]]
  //Output:[[1,2,3,4], [5,6]]
}

function arraysEqual(a, b) {
  if (a === b) return true;
  if (a == null || b == null) return false;
  if (a.length != b.length) return false;

  for (var i = 0; i < a.length; ++i) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}
相关问题