javascript中数组相交的最简单代码

javascript中数组相交的最简单代码,javascript,data-structures,intersection,Javascript,Data Structures,Intersection,在javascript中实现数组交叉点最简单、无库的代码是什么?我想写作 intersection([1,2,3], [2,3,4,5]) 得到 [2, 3] 结合使用和: 对于较旧的浏览器,无论是否具有箭头功能: var filteredArray = array1.filter(function(n) { return array2.indexOf(n) !== -1; }); 注意!.includes和.indexOf都使用=对数组中的元素进行内部比较,因此如果数组包含对象,

在javascript中实现数组交叉点最简单、无库的代码是什么?我想写作

intersection([1,2,3], [2,3,4,5])
得到

[2, 3]
结合使用和:

对于较旧的浏览器,无论是否具有箭头功能:

var filteredArray = array1.filter(function(n) {
    return array2.indexOf(n) !== -1;
});
注意!
.includes
.indexOf
都使用
=
对数组中的元素进行内部比较,因此如果数组包含对象,它将只比较对象引用(而不是其内容)。如果要指定自己的比较逻辑,请使用
。一些

  • 分类
  • 从索引0中逐个检查,然后从该索引创建新数组
  • 像这样的东西,虽然测试不好

    function intersection(x,y){
     x.sort();y.sort();
     var i=j=0;ret=[];
     while(i<x.length && j<y.length){
      if(x[i]<y[j])i++;
      else if(y[j]<x[i])j++;
      else {
       ret.push(x[i]);
       i++,j++;
      }
     }
     return ret;
    }
    
    alert(intersection([1,2,3], [2,3,4,5]));
    
    函数交点(x,y){
    x、 排序();
    var i=j=0;ret=[];
    
    而(i破坏性似乎最简单,尤其是如果我们可以假设输入是排序的:

    /* destructively finds the intersection of 
     * two arrays in a simple fashion.  
     *
     * PARAMS
     *  a - first array, must already be sorted
     *  b - second array, must already be sorted
     *
     * NOTES
     *  State of input arrays is undefined when
     *  the function returns.  They should be 
     *  (prolly) be dumped.
     *
     *  Should have O(n) operations, where n is 
     *    n = MIN(a.length, b.length)
     */
    function intersection_destructive(a, b)
    {
      var result = [];
      while( a.length > 0 && b.length > 0 )
      {  
         if      (a[0] < b[0] ){ a.shift(); }
         else if (a[0] > b[0] ){ b.shift(); }
         else /* they're equal */
         {
           result.push(a.shift());
           b.shift();
         }
      }
    
      return result;
    }
    
    /*以破坏性方式查找
    *以简单的方式创建两个数组。
    *
    *PARAMS
    *第一个数组,必须已排序
    *b-秒数组,必须已排序
    *
    *注释
    *输入数组的状态在以下情况下未定义:
    *函数返回。它们应该是
    *(prolly)被抛弃。
    *
    *应该有O(n)个操作,其中n是
    *n=最小值(a.长度,b.长度)
    */
    函数交点(a,b)
    {
    var结果=[];
    而(a.length>0&&b.length>0)
    {  
    如果(a[0]b[0]){b.shift();}
    else/*他们是平等的*/
    {
    结果:推(a.shift());
    b、 移位();
    }
    }
    返回结果;
    }
    
    非破坏性必须是一个更复杂的问题,因为我们必须跟踪索引:

    /* finds the intersection of 
     * two arrays in a simple fashion.  
     *
     * PARAMS
     *  a - first array, must already be sorted
     *  b - second array, must already be sorted
     *
     * NOTES
     *
     *  Should have O(n) operations, where n is 
     *    n = MIN(a.length(), b.length())
     */
    function intersect_safe(a, b)
    {
      var ai=0, bi=0;
      var result = [];
    
      while( ai < a.length && bi < b.length )
      {
         if      (a[ai] < b[bi] ){ ai++; }
         else if (a[ai] > b[bi] ){ bi++; }
         else /* they're equal */
         {
           result.push(a[ai]);
           ai++;
           bi++;
         }
      }
    
      return result;
    }
    
    /*查找
    *以简单的方式创建两个数组。
    *
    *PARAMS
    *第一个数组,必须已排序
    *b-秒数组,必须已排序
    *
    *注释
    *
    *应该有O(n)个操作,其中n是
    *n=最小值(a.长度(),b.长度())
    */
    安全功能(a、b)
    {
    var-ai=0,bi=0;
    var结果=[];
    while(aib[bi]){bi++;}
    else/*他们是平等的*/
    {
    结果:推(a[ai]);
    ai++;
    bi++;
    }
    }
    返回结果;
    }
    
    使用关联数组怎么样

    function intersect(a, b) {
        var d1 = {};
        var d2 = {};
        var results = [];
        for (var i = 0; i < a.length; i++) {
            d1[a[i]] = true;
        }
        for (var j = 0; j < b.length; j++) {
            d2[b[j]] = true;
        }
        for (var k in d1) {
            if (d2[k]) 
                results.push(k);
        }
        return results;
    }
    
    函数相交(a,b){
    var d1={};
    var d2={};
    var结果=[];
    对于(变量i=0;i
    编辑:

    //新版本
    函数相交(a,b){
    var d={};
    var结果=[];
    对于(变量i=0;i
    对于仅包含字符串或数字的数组,您可以按照其他一些答案进行排序。对于任意对象数组的一般情况,我认为您无法避免长时间进行排序。以下将为您提供作为
    arrayIntersection:

    var arrayContains = Array.prototype.indexOf ?
        function(arr, val) {
            return arr.indexOf(val) > -1;
        } :
        function(arr, val) {
            var i = arr.length;
            while (i--) {
                if (arr[i] === val) {
                    return true;
                }
            }
            return false;
        };
    
    function arrayIntersection() {
        var val, arrayCount, firstArray, i, j, intersection = [], missing;
        var arrays = Array.prototype.slice.call(arguments); // Convert arguments into a real array
    
        // Search for common values
        firstArray = arrays.pop();
        if (firstArray) {
            j = firstArray.length;
            arrayCount = arrays.length;
            while (j--) {
                val = firstArray[j];
                missing = false;
    
                // Check val is present in each remaining array 
                i = arrayCount;
                while (!missing && i--) {
                    if ( !arrayContains(arrays[i], val) ) {
                        missing = true;
                    }
                }
                if (!missing) {
                    intersection.push(val);
                }
            }
        }
        return intersection;
    }
    
    arrayIntersection( [1, 2, 3, "a"], [1, "a", 2], ["a", 1] ); // Gives [1, "a"]; 
    

    @atk实现的原语排序数组的性能可以通过使用.pop而不是.shift来提高

    function intersect(array1, array2) {
       var result = [];
       // Don't destroy the original arrays
       var a = array1.slice(0);
       var b = array2.slice(0);
       var aLast = a.length - 1;
       var bLast = b.length - 1;
       while (aLast >= 0 && bLast >= 0) {
          if (a[aLast] > b[bLast] ) {
             a.pop();
             aLast--;
          } else if (a[aLast] < b[bLast] ){
             b.pop();
             bLast--;
          } else /* they're equal */ {
             result.push(a.pop());
             b.pop();
             aLast--;
             bLast--;
          }
       }
       return result;
    }
    
    函数相交(array1,array2){
    var结果=[];
    //不要破坏原始阵列
    var a=阵列1.切片(0);
    var b=阵列2.切片(0);
    var aLast=a.长度-1;
    var bLast=b.长度-1;
    而(aLast>=0&&bLast>=0){
    如果(a[aLast]>b[bLast]){
    a、 pop();
    阿拉斯特--;
    }否则如果(a[aLast]
    我使用jsPerf创建了一个基准测试:。使用.pop大约快三倍。

    函数交叉点(a,B){
    
    function intersection(A,B){
    var result = new Array();
    for (i=0; i<A.length; i++) {
        for (j=0; j<B.length; j++) {
            if (A[i] == B[j] && $.inArray(A[i],result) == -1) {
                result.push(A[i]);
            }
        }
    }
    return result;
    }
    
    var result=新数组();
    对于(i=0;i,我将以最适合我的方式作出贡献:

    if (!Array.prototype.intersect){
    Array.prototype.intersect = function (arr1) {
    
        var r = [], o = {}, l = this.length, i, v;
        for (i = 0; i < l; i++) {
            o[this[i]] = true;
        }
        l = arr1.length;
        for (i = 0; i < l; i++) {
            v = arr1[i];
            if (v in o) {
                r.push(v);
            }
        }
        return r;
    };
    }
    
    if(!Array.prototype.intersect){
    Array.prototype.intersect=函数(arr1){
    var r=[],o={},l=this.length,i,v;
    对于(i=0;i
    使用jQuery:

    var a = [1,2,3];
    var b = [2,3,4,5];
    var c = $(b).not($(b).not(a));
    alert(c);
    
    以下是实施:

    _.intersection = function(array) {
      if (array == null) return [];
      var result = [];
      var argsLength = arguments.length;
      for (var i = 0, length = array.length; i < length; i++) {
        var item = array[i];
        if (_.contains(result, item)) continue;
        for (var j = 1; j < argsLength; j++) {
          if (!_.contains(arguments[j], item)) break;
        }
        if (j === argsLength) result.push(item);
      }
      return result;
    };
    
    intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]);
    // Expected: [ '1' ]
    // Actual: [ '1', '3' ]
    
    \交点=函数(数组){
    if(array==null)返回[];
    var结果=[];
    var argsLength=arguments.length;
    for(var i=0,length=array.length;i

    来源:

    另一种能够同时处理任意数量数组的索引方法:

    // Calculate intersection of multiple array or object values.
    function intersect (arrList) {
        var arrLength = Object.keys(arrList).length;
            // (Also accepts regular objects as input)
        var index = {};
        for (var i in arrList) {
            for (var j in arrList[i]) {
                var v = arrList[i][j];
                if (index[v] === undefined) index[v] = 0;
                index[v]++;
            };
        };
        var retv = [];
        for (var i in index) {
            if (index[i] == arrLength) retv.push(i);
        };
        return retv;
    };
    
    它仅适用于可作为字符串计算的值,您应将其作为数组传递,如:

    intersect ([arr1, arr2, arr3...]);
    
    …但它透明地接受对象作为参数或任何要相交的元素(始终返回公共值数组)。示例:

    intersect ({foo: [1, 2, 3, 4], bar: {a: 2, j:4}}); // [2, 4]
    intersect ([{x: "hello", y: "world"}, ["hello", "user"]]); // ["hello"]
    
    编辑:我刚刚注意到,在某种程度上,这是一个有点问题的问题

    也就是说:我编写它时认为输入数组本身不能包含重复(提供的示例不包含重复)

    但如果输入数组碰巧包含重复,则会产生错误的结果。示例(使用以下实现):

    幸运的是,只需添加二级索引即可轻松解决此问题。即:

    更改:

            if (index[v] === undefined) index[v] = 0;
            index[v]++;
    
    作者:

    ……和:

             if (index[i] == arrLength) retv.push(i);
    
    作者:

    完整示例:

    // Calculate intersection of multiple array or object values.
    function intersect (arrList) {
        var arrLength = Object.keys(arrList).length;
            // (Also accepts regular objects as input)
        var index = {};
        for (var i in arrList) {
            for (var j in arrList[i]) {
                var v = arrList[i][j];
                if (index[v] === undefined) index[v] = {};
                index[v][i] = true; // Mark as present in i input.
            };
        };
        var retv = [];
        for (var i in index) {
            if (Object.keys(index[i]).length == arrLength) retv.push(i);
        };
        return retv;
    };
    
    intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]); // [ '1' ]
    
    有一些限制
            if (index[v] === undefined) index[v] = {};
            index[v][i] = true; // Mark as present in i input.
    
             if (index[i] == arrLength) retv.push(i);
    
             if (Object.keys(index[i]).length == arrLength) retv.push(i);
    
    // Calculate intersection of multiple array or object values.
    function intersect (arrList) {
        var arrLength = Object.keys(arrList).length;
            // (Also accepts regular objects as input)
        var index = {};
        for (var i in arrList) {
            for (var j in arrList[i]) {
                var v = arrList[i][j];
                if (index[v] === undefined) index[v] = {};
                index[v][i] = true; // Mark as present in i input.
            };
        };
        var retv = [];
        for (var i in index) {
            if (Object.keys(index[i]).length == arrLength) retv.push(i);
        };
        return retv;
    };
    
    intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]); // [ '1' ]
    
    function intersectIntegers(array1,array2) { 
       var seen=[],
           result=[];
       for (var i = 0; i < array1.length; i++) {
         seen[array1[i]] = true;
       }
       for (var i = 0; i < array2.length; i++) {
         if ( seen[array2[i]])
            result.push(array2[i]);
       }
       return result;
    }
    
    function intersectObjects(array1,array2) { 
       var result=[];
       var key="tmpKey_intersect"
       for (var i = 0; i < array1.length; i++) {
         array1[i][key] = true;
       }
       for (var i = 0; i < array2.length; i++) {
         if (array2[i][key])
            result.push(array2[i]);
       }
       for (var i = 0; i < array1.length; i++) {
         delete array1[i][key];
       }
       return result;
    }
    
    function intersect(a, b) {
      var aa = {};
      a.forEach(function(v) { aa[v]=1; });
      return b.filter(function(v) { return v in aa; });
    }
    
    function intersect(a, b) {
      var setA = new Set(a);
      var setB = new Set(b);
      var intersection = new Set([...setA].filter(x => setB.has(x)));
      return Array.from(intersection);
    }
    
    function intersect(a, b) {
      var setB = new Set(b);
      return [...new Set(a)].filter(x => setB.has(x));
    }
    
    function intersect() { 
        const last = arguments.length - 1;
        var seen={};
        var result=[];
        for (var i = 0; i < last; i++)   {
            for (var j = 0; j < arguments[i].length; j++)  {
                if (seen[arguments[i][j]])  {
                    seen[arguments[i][j]] += 1;
                }
                else if (!i)    {
                    seen[arguments[i][j]] = 1;
                }
            }
        }
        for (var i = 0; i < arguments[last].length; i++) {
            if ( seen[arguments[last][i]] === last)
                result.push(arguments[last][i]);
            }
        return result;
    }
    
    _.intersection( [0,345,324] , [1,0,324] )  // gives [0,324]
    
    // Usage
    const intersection = allLists
      .reduce(intersect, allValues)
      .reduce(removeDuplicates, []);
    
    
    // Implementation
    const intersect = (intersection, list) =>
      intersection.filter(item =>
        list.some(x => x === item));
    
    const removeDuplicates = (uniques, item) =>
      uniques.includes(item) ? uniques : uniques.concat(item);
    
    
    // Example Data
    const somePeople = [bob, doug, jill];
    const otherPeople = [sarah, bob, jill];
    const morePeople = [jack, jill];
    
    const allPeople = [...somePeople, ...otherPeople, ...morePeople];
    const allGroups = [somePeople, otherPeople, morePeople];
    
    // Example Usage
    const intersection = allGroups
      .reduce(intersect, allPeople)
      .reduce(removeDuplicates, []);
    
    intersection; // [jill]
    
    function intersection (a, b) {
      var seen = a.reduce(function (h, k) {
        h[k] = true;
        return h;
      }, {});
    
      return b.filter(function (k) {
        var exists = seen[k];
        delete seen[k];
        return exists;
      });
    }
    
    function getIntersection(arr1, arr2){
        var result = [];
        arr1.forEach(function(elem){
            arr2.forEach(function(elem2){
                if(elem === elem2){
                    result.push(elem);
                }
            });
        });
        return result;
    }
    
    getIntersection([1,2,3], [2,3,4,5]); // [ 2, 3 ]
    
    function intersect_1d( a, b ){
        var out=[], ai=0, bi=0, acurr, bcurr, last=Number.MIN_SAFE_INTEGER;
        while( ( acurr=a[ai] )!==undefined && ( bcurr=b[bi] )!==undefined ){
            if( acurr < bcurr){
                if( last===acurr ){
                    out.push( acurr );
                }
                last=acurr;
                ai++;
            }
            else if( acurr > bcurr){
                if( last===bcurr ){
                    out.push( bcurr );
                }
                last=bcurr;
                bi++;
            }
            else {
                out.push( acurr );
                last=acurr;
                ai++;
                bi++;
            }
        }
        return out;
    }
    
    function intersection(arr1, arr2) {
      var myObj = {};
      var myArr = [];
      for (var i = 0, len = arr1.length; i < len; i += 1) {
        if(myObj[arr1[i]]) {
          myObj[arr1[i]] += 1; 
        } else {
          myObj[arr1[i]] = 1;
        }
      }
      for (var j = 0, len = arr2.length; j < len; j += 1) {
        if(myObj[arr2[j]] && myArr.indexOf(arr2[j]) === -1) {
          myArr.push(arr2[j]);
        }
      }
      return myArr;
    }
    
    function intersectionOfArrays(arr1, arr2) {
        return arr1.filter((element) => arr2.indexOf(element) !== -1).filter((element, pos, self) => self.indexOf(element) == pos);
    }
    
    if arr1 = [{id: 10}, {id: 20}]
    and arr2 =  [{id: 20}, {id: 25}]
    
    [{id: 20}]
    
    const intersect = (arr1, arr2, accessors = [v => v, v => v]) => {
        const [fn1, fn2] = accessors;
        const set = new Set(arr2.map(v => fn2(v)));
        return arr1.filter(value => set.has(fn1(value)));
    };
    
    intersect(arr1, arr2, [elem => elem.id, elem => elem.id])
    
    function array_intersect(array1, array2) 
    {
        var mergedElems = {},
            result = [];
    
        // Returns a unique reference string for the type and value of the element
        function generateStrKey(elem) {
            var typeOfElem = typeof elem;
            if (typeOfElem === 'object') {
                typeOfElem += Object.prototype.toString.call(elem);
            }
            return [typeOfElem, elem.toString(), JSON.stringify(elem)].join('__');
        }
    
        array1.forEach(function(elem) {
            var key = generateStrKey(elem);
            if (!(key in mergedElems)) {
                mergedElems[key] = {elem: elem, inArray2: false};
            }
        });
    
        array2.forEach(function(elem) {
            var key = generateStrKey(elem);
            if (key in mergedElems) {
                mergedElems[key].inArray2 = true;
            }
        });
    
        Object.values(mergedElems).forEach(function(elem) {
            if (elem.inArray2) {
                result.push(elem.elem);
            }
        });
    
        return result;
    }
    
    function array_intersect(array1, array2) 
    {
        var mergedElems = {},
            result = [],
            firstArray, secondArray,
            firstN = 0, 
            secondN = 0;
    
        function generateStrKey(elem) {
            var typeOfElem = typeof elem;
            if (typeOfElem === 'object') {
                typeOfElem += Object.prototype.toString.call(elem);
            }
            return [typeOfElem, elem.toString(), JSON.stringify(elem)].join('__');
        }
    
        // Executes the loops only if both arrays have values
        if (array1.length && array2.length) 
        {
            // Begins with the shortest array to optimize the algorithm
            if (array1.length < array2.length) {
                firstArray = array1;
                secondArray = array2;
            } else {
                firstArray = array2;
                secondArray = array1;            
            }
    
            firstArray.forEach(function(elem) {
                var key = generateStrKey(elem);
                if (!(key in mergedElems)) {
                    mergedElems[key] = {elem: elem, inArray2: false};
                    // Increases the counter of unique values in the first array
                    firstN++;
                }
            });
    
            secondArray.some(function(elem) {
                var key = generateStrKey(elem);
                if (key in mergedElems) {
                    if (!mergedElems[key].inArray2) {
                        mergedElems[key].inArray2 = true;
                        // Increases the counter of matches
                        secondN++;
                        // If all elements of first array have coincidence, then exits the loop
                        return (secondN === firstN);
                    }
                }
            });
    
            Object.values(mergedElems).forEach(function(elem) {
                if (elem.inArray2) {
                    result.push(elem.elem);
                }
            });
        }
    
        return result;
    }