在JavaScript

时间:2017-12-12 06:16:22

标签: javascript

对于day 12 of Advent of Code我有一个解决方案,我最终得到这种结构:

let structure = new Set([
    new Set(["1", "42"]),
    new Set(["42"]),
    new Set(["1", "42"])
]);

起初,我天真地期望上述内容与此相同:

let expected = new Set([
    new Set(["1", "42"]),
    new Set(["42"])
]);

但当然没有发生这种情况,因为structure中的第1和第3集是不同的对象,所以外部集不会重复它们。

请注意,实际上我有200套,都包含1到10个项目,因此解决方案必须正常运行。

我能够使用在最前沿浏览器中运行的任何现代JS(例如Chrome 63+),并且如果可能的话,我更倾向于使用vanilla JavaScript。

expected或其内部数组作为起点的情况下,只有2个不同的集合来获取structure结果的有效方法是什么?

4 个答案:

答案 0 :(得分:1)

要识别重复项,请使用lodash' isEqual(),或实施等效的isEqual()函数来比较两组(见下文)。

将其与reduce()函数相结合,将不同的集合添加到最终结果集中。

let structure = new Set([
    new Set(["1", "42"]),
    new Set(["42"]),
    new Set(["42", "1"])
]);

function isEqual(set1, set2) {
  let s1 = Array.from(set1).sort();
  let s2 = Array.from(set2).sort();
  if (s1.length != s2.length)
     return false;

  for (let i = 0; i < s1.length; i++) 
    if (s1[i] !== s2[i])
       return false;

  return true;
}

let outerSetArray = Array.from(structure);
let deduplicated = outerSetArray.reduce((aggregator, innerSet) => {
  if (!aggregator.some(s => isEqual(s, innerSet)))
      aggregator.push(innerSet);

  return aggregator;
}, []);

现在deduplicated是一组不同的集合,如果需要,您可以将其转回Set

答案 1 :(得分:1)

这可能有点贵,但会完成工作。我不确定这可能带来多少计算上的不良影响。

策略1:

  • 使用JSON.stringify创建一个包含字符串化数组的集。
  • 使用JSON.parse将Set元素转换回数组。

策略2:

  • 创建一个值为&#34的对象; - &#34;加入了字符串。
  • 通过映射键重新构建数组,并使用&#34; - &#34;分隔符。

&#13;
&#13;
// JSON STRINGIFY - JSON PARSE STRATEGY

let structure = new Set([
    new Set(["1", "42"]),
    new Set(["42"]),
    new Set(["1", "42"])
]);

const json_stringified_set = new Set([...structure].map(a => JSON.stringify([...a])))

const json_parsed_set = new Set([...json_stringified_set].map(a => JSON.parse(a)))

console.log([...json_parsed_set]);


// REDUCE - OBJECT STRATEGY

const reduced_object = [...structure].reduce((a, b) => { a[[...b].join("-")] = ""; return a }, {})

const final_set = new Set(Object.keys(reduced_object).map(a => a.split("-")))

console.log([...final_set])
&#13;
&#13;
&#13;

答案 2 :(得分:1)

 function filterUniqueSets(...sets){
   const hash = {};
   return sets.filter(set => {
     const k = [...set].join("¢");
     if(hash[k]) return false;
     return hash[k] = true;
  });
}

所以可以这样做:

 const result = new Set(filterUniqueSets(
   new Set(1,2,3),
   new Set(1,3,4)
 ));

答案 3 :(得分:0)

也许你可以使用这样的东西:

function same(val1, val2){
  var v1, v2, s;
  if(val1 instanceof Array && val2 instanceof Array){
    var l = val1.length;
    if(l !== val2.length){
      return false;
    }
    for(var i=0; i<l; i++){
      v1 = val1[i]; v2 = val2[i];
      if(typeof v1 === 'object' || typeof v2 === 'object'){
        if(!same(v1, v2)){
          return false;
        }
      }
      else if(v1 !== v2){
        return false;
      }
    }
  }
  else if(typeof val1 === 'object' && typeof val2 === 'object'){
    for(var i in val1){
      v1 = val1[i]; v2 = val2[i];
      if(typeof v1 === 'object' || typeof v2 === 'object'){
        if(!same(v1, v2)){
          return false;
        }
      }
      else{
        if(!(i in val2)){
          return false;
        }
        if(v1 !== v2){
          return false;
        }
      }
    }
  }
  else if(val1 !== val2){
    return false;
  }
  return true;
}
console.log(same(4, 4));
console.log(same(['w', 'f', 't', 4], ['w', 't', 'f', 4]));
console.log(same(['w', 't', 'f', 4], ['w', 't', 'f', 4]));
var obj1 = {here: ['a', 'b', 3], test:4, obj:{wow:[4, 'real'], cool:'works'}};
var obj2 = {here: ['a', 'b', 3], test:4, obj:{wow:[4, 'real'], cool:'works'}};
var obj3 = {here: ['a', 'b', 3], test:4, obj:{wow:[2, 'real'], cool:'works'}};
console.log(same(obj1, obj2)); console.log(same(obj1, obj3));