繁体   English   中英

在JavaScript中的多个数组中查找对称差/唯一元素

[英]finding symmetric difference/unique elements in multiple arrays in javascript

嗨,我正在努力解决这个问题。 如何创建一个以任意数量的数组作为参数的javascript函数,然后返回仅出现在其中一个数组中的元素数组。 出现在多个阵列中的所有项目均被删除。 解决方案一无所获,怀疑我没有以正确的方式进行处理,陷入困境!

编辑:另一个问题解决了消除一个数组中的重复值的问题,我需要比较x个单独的数组的数目,并返回在数组之间不重复的值。 因此([5,6,7],[5,8,9])返回[6,7,8,9]。

function sym(args) {
  var ans = [];


  for(var i =0;i<arguments.length;i++){
    var tempArr = arguments[i].filter(function(el){
      var filtTrue = false;
       for(var j = 0;j<arguments.length;j++){
         if(Array.isArray(arguments[j]) && arguments[j] !== arguments[i]){
           if(arguments[j].indexOf(el) === -1){
             filtTrue = true;
              }}
        }
           return filtTrue;
          });
           ans = ans.concat(tempArr);
  }



    return ans;
  }

这是一种方法。 这里的想法是创建一个映射以保留数组中所有项目的计数。 然后,您遍历每个数组,在映射中查找每个值,如果找到,则增加其计数。 如果未找到,则将计数设置为1。然后,在处理完所有阵列后,将收集计数为1的所有项目。

您不确定要在同一阵列中多次出现某项,而在其他任何阵列中均未出现一次该怎么办。 第一个解决方案将不包括该项目(因为它检测到重复项)。 如果有问题,可以对其进行修改(稍微复杂一些)以允许该项目(有关实现,请参见下面的第二代码块)。

function sym(/* pass one or more arrays here */) {
    var ans = [], cnts = {};

    //count all items in the array
    for (var i = 0; i < arguments.length; i++){
        arguments[i].forEach(function(item) {
            if (cnts.hasOwnProperty(item)) {
                // increase cnt
                ++cnts[item].cnt;
            } else {
                // initalize cnt and value
                cnts[item] = {cnt: 1, val: item};
            }
        });
    }
    for (var item in cnts) {
        if (cnts.hasOwnProperty(item) && cnts[item].cnt === 1) {
            ans.push(cnts[item].val);
        }
    }

    return ans;
}

如果要在单个数组中包含多次出现但在其他任何数组中都不存在的项,则可以使用这种稍微复杂一点的修改:

function sym(/* pass one or more arrays here */) {
    var ans = [], cnts = {}, currentMap;

    //count all items in the array
    for (var i = 0; i < arguments.length; i++){
        currentMap = {};
        arguments[i].forEach(function(item) {
            // if we haven't already counted this item in this array
            if (!currentMap.hasOwnProperty(item)) {
                if (cnts.hasOwnProperty(item)) {
                    // increase cnt
                    ++cnts[item].cnt;
                } else {
                    // initalize cnt and value
                    cnts[item] = {cnt: 1, val: item};
                }
            }
            // keep track of whethere we've already counted this item in this array
            currentMap[item] = true;
        });
    }
    // output all items that have a cnt of 1
    for (var item in cnts) {
        if (cnts.hasOwnProperty(item) && cnts[item].cnt === 1) {
            ans.push(cnts[item].val);
        }
    }

    return ans;
}

工作演示: http : //jsfiddle.net/jfriend00/bete5k3n/

我知道这很晚了,但这是另一种方式。 也许不是最严格的,但肯定是有创造力的。 方法Array.symmetricDifference()需要任意数量的参数,并返回这些参数的对称差。

Array.prototype.symmetricDifference = function() {
  var args = [];

  // copy arguments into a real array and get rid of duplicates with filter
  for(var i = 0; i < arguments.length; i++) {
    args[i] = arguments[i];
    args[i] = args[i].filter(function(item, pos, self) {
      return self.indexOf(item) == pos;
    });
  }
  var diff = args[0];

  // iterate through every arguments in args.
  // concatenate the first two arguments to form a new set.
  // now every number in this new set that was contained in both arguments
  // from before will be contained at least twice in this new set.
  for(var j = 1; j < args.length; j++) {
    //sort the new set so that duplicates are next to each other.
    diff = diff.concat(args[j]).sort();
    var index = 0;

    // now iterate through the new set and delete both duplicates if you
    // find any. Otherwise proceed to the next index.
    while(index < diff.length) {
      // if duplicate is found delete both, otherwise look at next index.
      diff[index] === diff[index + 1] ? diff.splice(index, 2) : index++;
    }
  }
  return diff;
};

您可以在任何数组上调用该方法,也可以创建一个新数组,然后在该数组上调用它,例如:

// take any number of arrays
var a = [3, 3, 3, 2, 5];
var b = [2, 1, 5, 7];
var c = [3, 4, 6, 6];
var d = [1, 2, 3];
var e = [5, 3, 9, 8];
var f = [1];

// invoke the method on "solution" with any number of arguments
// and store it in solution.
var solution = solution.symmetricDifference(a,b,c,d,e,f);

console.log(solution); // [1, 2, 4, 5, 6, 7, 8, 9]

我希望这有帮助!

在多个数组中查找唯一项

 function uniqueItemsInArrays(...args){ let allItems = []; allItems = allItems.concat(...args) return allItems.filter(function(item, pos, self) { return self.indexOf(item) === pos && self.indexOf(item,pos+1) === -1; }); } uniqueItemsInArrays( [1, 5, 1, 8, 1, 2], [2, 2, 9, 3, 5], [1, 4, 7, 6] ); 

上面的代码使用ES6 rest参数访问作为参数传递的所有数组。 然后使用concat()函数,将所有单个数组连接到单个数组。 最后,过滤器功能已用于识别并返回此数组中的唯一项。 这里的逻辑是找出当前项目的第一个索引,如果第一个索引中没有更多的索引,那么我们返回该项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM