试图解决使用Javascript对称差 [英] Trying to solve symmetric difference using Javascript

查看:163
本文介绍了试图解决使用Javascript对称差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出对称解决方案
区别使用的JavaScript实现以下
目标:


  • 接受数组数目不详作为参数

  • preserves在阵列数字的原始顺序

  • 不会删除号码的重复单阵列

  • 删除跨阵列发生重复

因此​​,例如,
如果输入是([1,1,2,6],[2,3,5],[2,3,4]),
该解决方案将是,[1,1,6,5,4]。

我试图解决这个通过网上定质询
编码社区。挑战的确切指示
状态,


  

创建一个函数,它接受两个或两个以上的阵列,并返回一个数组
  所提供的阵列的对称差


  
  

数学术语对称差是指在元件
  两组是在第一或第二组,但不是在两个


虽然我的解决方案如下认定是数字
唯一的每个阵列,它消除了存在的所有数字
不止一次并且不保留编号的顺序。

我的问题是非常接近那个在<一问href=\"http://stackoverflow.com/questions/30468692/finding-symmetric-difference-unique-elements-in-multiple-arrays-in-javascript\">finding在JavaScript的多个阵列对称差/独特的元素。然而,该解决方案
没有preserve数字的原始顺序,并没有单一阵列中发生唯一编码preserve重复。

 函数符号(参数){
    VAR ARR = [];
    VAR的结果= [];
    VAR单位;
    VAR指数= {};
    对(在参数变种I){
        单位=参数[I]    对于(VAR J = 0; J&LT; units.length; J ++){
         arr.push(单位[J]);
        }
    }    arr.forEach(函数(){
        如果(!指数[A]){
            指数[A] = 0;
        }
            指数[A] ++;    });       对于(VAR升的指数){
           如果(指数[L] === 1){
               result.push(+ 1);
           }
       }    返回结果;
}
symsym([1,1,2,6],[2,3,5],[2,3,4]); // =&GT;期望中的答案:1,1,6 5 4]


解决方案

下面是一个使用设置对象,以更快的查找一个版本。这里的基本逻辑:


  1. 把它作为参数传递到单独设置对象的每个阵列(旨在便利快速查找)。

  2. 然后,它遍历数组中的每一个传递,并将其与另一组对象(不是从数组所做的那些被迭代)。

  3. 如果在任何其它组中都没有找到的项目,然后它被加入到结果。

所以,它与第一阵列开始 [1,1,2,6] 。由于 1 无论是在其它阵列中都没有找到,每前两个 1 值被添加到结果。然后 2 在第二盘被发现,因此不会被添加到结果。然后 6 未在任一其他两组发现因此被添加到结果。同样的过程重复第二阵列 [2,3,5] ,其中 2 3 在其他组被发现,但 5 不是那么 5 添加到结果。而且,在过去的阵列,只有 4 未在其他集合中。所以,最后的结果是 [1,1,6,5,4]

设置对象用于方便和性能。人们可以使用 .indexOf()来看看他们每个阵列中或者一个可以使一个普通的对象,你自己的一套类似的查找,如果你不想依赖设置对象。还有用于设置对象,将工作在这里这个答案

\r
\r

函数symDiff(){\r
    VAR套= [],结果= [];\r
    //使参数拷贝到一个数组\r
    变参= Array.prototype.slice.call(参数,0);\r
    //把每个阵列成一组,方便查找\r
    args.forEach(功能(ARR){\r
        sets.push(新集(ARR));\r
    });\r
    //现在看到每个数组中的元素是唯一\r
    //例如不包含在其它组\r
    args.forEach(函数(数组,arrayIndex){\r
        //循环阵列中的每个项\r
        array.forEach(函数(项目){\r
            VAR发现= FALSE;\r
            //遍历每一组(使用普通的for循环,以便更容易打破)\r
            为(VAR setIndex = 0; setIndex&下; sets.length; setIndex ++){\r
                //从我们自己的阵列跳过集\r
                如果(setIndex!== arrayIndex){\r
                    如果(套[setIndex]。先后(项目)){\r
                        //如果set这个项目\r
                        发现= TRUE;\r
                        打破;\r
                    }\r
                }\r
            }\r
            如果(!找到){\r
                result.push(项目);\r
            }\r
        });\r
    });\r
    返回结果;\r
}\r
\r
变种R = symDiff([1,1,2,6],[2,3,5],[2,3,4]);\r
日志(R);\r
\r
函数日志(x)的{\r
    变种D =使用document.createElement(分区);\r
    d.textContent = JSON.stringify(X);\r
    document.body.appendChild(四);\r
}

\r

\r
\r

这code的一个关键部分是如何在给定的项目进行比较,从其他阵列的设置。它只是通过设置对象的列表上循环,但它跳过了数组中相同的索引数组正在迭代设置对象。这将跳过所以它只能寻找存在于其他阵列物品从这个数组所做的设置。允许其保留中出现的唯一的一个阵列的重复


下面是一个使用,如果它是present的设置对象的一个​​版本,但插入一个极小的更换,如果没有(那么这将工作在更老的浏览器):

\r
\r

函数symDiff(){\r
    VAR套= [],结果= [],LocalSet;\r
    如果(typeof运算设置===功能){\r
        尝试{\r
            //测试以查看是否支持构造精氨酸可迭代\r
            变种临时=新集([1,2,3]);\r
            如果(temp.size === 3){\r
                LocalSet =设置;\r
            }\r
        }赶上(E){}\r
    }\r
    如果(!LocalSet){\r
        //用于设置蝇头填充工具\r
        LocalSet =功能(ARR){\r
            this.has =功能(项目){\r
                返回arr.indexOf(项目)== -1!;\r
            }\r
        }\r
    }\r
    //使参数拷贝到一个数组\r
    变参= Array.prototype.slice.call(参数,0);\r
    //把每个阵列成一组,方便查找\r
    args.forEach(功能(ARR){\r
        sets.push(新LocalSet(ARR));\r
    });\r
    //现在看到每个数组中的元素是唯一\r
    //例如不包含在其它组\r
    args.forEach(函数(数组,arrayIndex){\r
        //循环阵列中的每个项\r
        array.forEach(函数(项目){\r
            VAR发现= FALSE;\r
            //遍历每一组(使用普通的for循环,以便更容易打破)\r
            为(VAR setIndex = 0; setIndex&下; sets.length; setIndex ++){\r
                //从我们自己的阵列跳过集\r
                如果(setIndex!== arrayIndex){\r
                    如果(套[setIndex]。先后(项目)){\r
                        //如果set这个项目\r
                        发现= TRUE;\r
                        打破;\r
                    }\r
                }\r
            }\r
            如果(!找到){\r
                result.push(项目);\r
            }\r
        });\r
    });\r
    返回结果;\r
}\r
\r
\r
变种R = symDiff([1,1,2,6],[2,3,5],[2,3,4]);\r
日志(R);\r
\r
函数日志(x)的{\r
    变种D =使用document.createElement(分区);\r
    d.textContent = JSON.stringify(X);\r
    document.body.appendChild(四);\r
}

\r

\r
\r

I am trying to figure out a solution for symmetric difference using javascript that accomplishes the following objectives:

  • accepts an unspecified number of arrays as arguments
  • preserves the original order of the numbers in the arrays
  • does not remove duplicates of numbers in single arrays
  • removes duplicates occurring across arrays

Thus, for example, if the input is ([1, 1, 2, 6], [2, 3, 5], [2, 3, 4]), the solution would be, [1, 1, 6, 5, 4].

I am trying to solve this as challenge given by an online coding community. The exact instructions of the challenge state,

Create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays.

The mathematical term symmetric difference refers to the elements in two sets that are in either the first or second set, but not in both.

Although my solution below finds the numbers that are unique to each array, it eliminates all numbers occuring more than once and does not keep the order of the numbers.

My question is very close to the one asked at finding symmetric difference/unique elements in multiple arrays in javascript. However, the solution does not preserve the original order of the numbers and does not preserve duplicates of unique numbers occurring in single arrays.

function sym(args){
    var arr = [];
    var result = [];
    var units;
    var index = {};
    for(var i in arguments){
        units = arguments[i];

    for(var j = 0; j < units.length; j++){
         arr.push(units[j]);
        }
    }

    arr.forEach(function(a){
        if(!index[a]){
            index[a] = 0;
        }
            index[a]++;

    });

       for(var l in index){
           if(index[l] === 1){
               result.push(+l);
           }
       }

    return result;
}
symsym([1, 1, 2, 6], [2, 3, 5], [2, 3, 4]); // => Desired answer: [1, 1, 6. 5. 4]

解决方案

Here's a version that uses the Set object to make for faster lookup. Here's the basic logic:

  1. It puts each array passed as an argument into a separate Set object (to faciliate fast lookup).
  2. Then, it iterates each passed in array and compares it to the other Set objects (the ones not made from the array being iterated).
  3. If the item is not found in any of the other Sets, then it is added to the result.

So, it starts with the first array [1, 1, 2, 6]. Since 1 is not found in either of the other arrays, each of the first two 1 values are added to the result. Then 2 is found in the second set so it is not added to the result. Then 6 is not found in either of the other two sets so it is added to the result. The same process repeats for the second array [2, 3, 5] where 2 and 3 are found in other Sets, but 5 is not so 5 is added to the result. And, for the last array, only 4 is not found in the other Sets. So, the final result is [1,1,6,5,4].

The Set objects are used for convenience and performance. One could use .indexOf() to look them up in each array or one could make your own Set-like lookup with a plain object if you didn't want to rely on the Set object. There's also a partial polyfill for the Set object that would work here in this answer.

function symDiff() {
    var sets = [], result = [];
    // make copy of arguments into an array
    var args = Array.prototype.slice.call(arguments, 0);
    // put each array into a set for easy lookup
    args.forEach(function(arr) {
        sets.push(new Set(arr));
    });
    // now see which elements in each array are unique 
    // e.g. not contained in the other sets
    args.forEach(function(array, arrayIndex) {
        // iterate each item in the array
        array.forEach(function(item) {
            var found = false;
            // iterate each set (use a plain for loop so it's easier to break)
            for (var setIndex = 0; setIndex < sets.length; setIndex++) {
                // skip the set from our own array
                if (setIndex !== arrayIndex) {
                    if (sets[setIndex].has(item)) {
                        // if the set has this item
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                result.push(item);
            }
        });
    });
    return result;
}

var r = symDiff([1, 1, 2, 6], [2, 3, 5], [2, 3, 4]);
log(r);

function log(x) {
    var d = document.createElement("div");
    d.textContent = JSON.stringify(x);
    document.body.appendChild(d);
}

One key part of this code is how it compares a given item to the Sets from the other arrays. It just iterates through the list of Set objects, but it skips the Set object that has the same index in the array as the array being iterated. That skips the Set made from this array so it's only looking for items that exist in other arrays. That allows it to retain duplicates that occur in only one array.


Here's a version that uses the Set object if it's present, but inserts a teeny replacement if not (so this will work in more older browsers):

function symDiff() {
    var sets = [], result = [], LocalSet;
    if (typeof Set === "function") {
        try {
            // test to see if constructor supports iterable arg
            var temp = new Set([1,2,3]);
            if (temp.size === 3) {
                LocalSet = Set;
            }
        } catch(e) {}
    }
    if (!LocalSet) {
        // use teeny polyfill for Set
        LocalSet = function(arr) {
            this.has = function(item) {
                return arr.indexOf(item) !== -1;
            }
        }
    }
    // make copy of arguments into an array
    var args = Array.prototype.slice.call(arguments, 0);
    // put each array into a set for easy lookup
    args.forEach(function(arr) {
        sets.push(new LocalSet(arr));
    });
    // now see which elements in each array are unique 
    // e.g. not contained in the other sets
    args.forEach(function(array, arrayIndex) {
        // iterate each item in the array
        array.forEach(function(item) {
            var found = false;
            // iterate each set (use a plain for loop so it's easier to break)
            for (var setIndex = 0; setIndex < sets.length; setIndex++) {
                // skip the set from our own array
                if (setIndex !== arrayIndex) {
                    if (sets[setIndex].has(item)) {
                        // if the set has this item
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                result.push(item);
            }
        });
    });
    return result;
}


var r = symDiff([1, 1, 2, 6], [2, 3, 5], [2, 3, 4]);
log(r);

function log(x) {
    var d = document.createElement("div");
    d.textContent = JSON.stringify(x);
    document.body.appendChild(d);
}

这篇关于试图解决使用Javascript对称差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆