web-dev-qa-db-ja.com

JavaScriptでの配列交差のための最も簡単なコード

JavaScriptで配列の交差を実装するための最も簡単でライブラリ不要のコードは何ですか?書きたい

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

そして得る

[2, 3]
470
Peter

Array.prototype.filterArray.prototype.indexOf の組み合わせを使用します。

array1.filter(value => -1 !== array2.indexOf(value))

または vrugtehagel がコメントで提案しているように、もっと単純なコードにはもっと新しい Array.prototype.includes を使うことができます。

array1.filter(value => array2.includes(value))

古いブラウザの場合:

array1.filter(function(n) {
    return array2.indexOf(n) !== -1;
});
860
Anon.

特に入力がソートされていると仮定できる場合、破壊的な処理は最も単純に見えます。

/* 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;
}

インデックスを追跡する必要があるため、非破壊的な方法はさらに複雑になります。

/* 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;
}
155
atk

あなたの環境が ECMAScript 6 Set をサポートしているなら、1つの単純で効率的な方法(仕様リンク参照)

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);
}

短くなりますが読みにくくなります(追加の共通部分Setも作成しないでください)。

function intersect(a, b) {
      return [...new Set(a)].filter(x => new Set(b).has(x));
}

毎回Setから新しいbを避けること:

function intersect(a, b) {
      var setB = new Set(b);
      return [...new Set(a)].filter(x => setB.has(x));
}

集合を使うときは、異なる値しか得られないので、new Set[1,2,3,3].size3に評価されます。

46
nbarbosa

Underscore.jsを使用する または lodash.js

_.intersection( [0,345,324] , [1,0,324] )  // gives [0,324]
28
Sai Ram

ES6の言葉で私の貢献。一般的に、引数として提供された配列の不定数と配列の共通部分を見つけます。

Array.prototype.intersect = function(...a) {
  return [this,...a].reduce((p,c) => p.filter(e => c.includes(e)));
}
var arrs = [[0,2,4,6,8],[4,5,6,7],[4,6]],
     arr = [0,1,2,3,4,5,6,7,8,9];

document.write("<pre>" + JSON.stringify(arr.intersect(...arrs)) + "</pre>");
12
Redu

連想配列を使うだけではどうでしょうか。

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;
}

編集:

// new version
function intersect(a, b) {
    var d = {};
    var results = [];
    for (var i = 0; i < b.length; i++) {
        d[b[i]] = true;
    }
    for (var j = 0; j < a.length; j++) {
        if (d[a[j]]) 
            results.Push(a[j]);
    }
    return results;
}
11
Steven Huwig

jQuery を使用する

var a = [1,2,3];
var b = [2,3,4,5];
var c = $(b).not($(b).not(a));
alert(c);
8
Gowsikan

プリミティブのソートされた配列に対する@ atkの実装のパフォーマンスは、.shiftではなく.popを使用することで改善できます。

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;
}

JsPerfを使ってベンチマークを作成しました: http://bit.ly/P9FrZK 。 .popを使うのは約3倍高速です。

8
xn.
// Return elements of array a that are also in b in linear time:
function intersect(a, b) {
  return a.filter(Set.prototype.has, new Set(b));
}

// Example:
console.log(intersect([1,2,3], [2,3,4,5]));

私は上記の簡潔な解決策をお勧めします。これは大きな入力に対して他の実装よりも優れています。小さな入力でのパフォーマンスが問題になる場合は、以下の選択肢を確認してください。

代替案とパフォーマンスの比較:

代替の実装については次のスニペットを参照し、パフォーマンスの比較については https://jsperf.com/array-intersection-comparison を確認してください。

function intersect_for(a, b) {
  const result = [];
  const alen = a.length;
  const blen = b.length;
  for (let i = 0; i < alen; ++i) {
    const ai = a[i];
    for (let j = 0; j < blen; ++j) {
      if (ai === b[j]) {
        result.Push(ai);
        break;
      }
    }
  } 
  return result;
}

function intersect_filter_indexOf(a, b) {
  return a.filter(el => b.indexOf(el) !== -1);
}

function intersect_filter_in(a, b) {
  const map = b.reduce((map, el) => {map[el] = true; return map}, {});
  return a.filter(el => el in map);
}

function intersect_for_in(a, b) {
  const result = [];
  const map = {};
  for (let i = 0, length = b.length; i < length; ++i) {
    map[b[i]] = true;
  }
  for (let i = 0, length = a.length; i < length; ++i) {
    if (a[i] in map) result.Push(a[i]);
  }
  return result;
}

function intersect_filter_includes(a, b) {
  return a.filter(el => b.includes(el));
}

function intersect_filter_has_this(a, b) {
  return a.filter(Set.prototype.has, new Set(b));
}

function intersect_filter_has_arrow(a, b) {
  const set = new Set(b);
  return a.filter(el => set.has(el));
}

function intersect_for_has(a, b) {
  const result = [];
  const set = new Set(b);
  for (let i = 0, length = a.length; i < length; ++i) {
    if (set.has(a[i])) result.Push(a[i]);
  }
  return result;
}

Firefox 53の結果:

  • 大規模アレイでのOps/sec(10,000要素):

    filter + has (this)               523 (this answer)
    for + has                         482
    for-loop + in                     279
    filter + in                       242
    for-loops                          24
    filter + includes                  14
    filter + indexOf                   10
    
  • 小さなアレイでのOps/sec(100要素):

    for-loop + in                 384,426
    filter + in                   192,066
    for-loops                     159,137
    filter + includes             104,068
    filter + indexOf               71,598
    filter + has (this)            43,531 (this answer)
    filter + has (arrow function)  35,588
    
8
le_m

文字列や数字だけを含む配列の場合、他のいくつかの答えのように、ソートで何かをすることができます。任意のオブジェクトの配列の一般的なケースでは、私はあなたがそれを遠いやり方ですることを避けることができるとは思わない。以下は、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"]; 
7
Tim Down

ES2015とSetsを使うとかなり短いです。文字列のような配列のような値を受け入れ、重複を取り除きます。

let intersection = function(a, b) {
  a = new Set(a), b = new Set(b);
  return [...a].filter(v => b.has(v));
};

console.log(intersection([1,2,1,2,3], [2,3,5,4,5,3]));

console.log(intersection('ccaabbab', 'addb').join(''));
7
SeregPie
  1. 並べ替え
  2. インデックス0から1つずつチェックし、そこから新しい配列を作成します。

このようなもの、よくテストされていません。

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]));

PS:このアルゴリズムはNumbersとNormal Stringsのみを対象としており、任意のオブジェクト配列の交差は機能しない可能性があります。

7
YOU

ここで最小のもの( filter/indexOfソリューション )を少し微調整すると、JavaScriptオブジェクトを使用していずれかの配列の値のインデックスを作成すると、O(N * M)から "おそらく"になります。 "線形時間です。 source1source2

function intersect(a, b) {
  var aa = {};
  a.forEach(function(v) { aa[v]=1; });
  return b.filter(function(v) { return v in aa; });
}

これは( filter + indexOf よりコードが多い)最も単純な解決策ではありませんし、( intersect_safe() よりも定数倍遅い)おそらく最も速い方法でもありませんが、かなりのようです良いバランス very simple側にありますが、優れたパフォーマンスを提供します。また、事前にソートされた入力を必要としません。

5
David

任意の数の配列を一度に処理できるもう1つの索引付きアプローチ:

// 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"]

編集: ある意味、これは少しバグがあることに気付いた。

つまり、入力配列自体に繰り返しを含めることはできないと考えてコーディングしました(提供されている例では含まれていません)。

しかし、入力配列に繰り返しが含まれていると、誤った結果が生じます。例(以下の実装を使用):

intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]);
// Expected: [ '1' ]
// Actual: [ '1', '3' ]

幸いなことに、これは単に第2レベルのインデックスを追加することで簡単に修正できます。あれは:

変化する:

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

によって:

        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' ]
5
bitifet

データにいくつかの制限がありますが、 linear timeで実行できます。

正の整数の場合 :値を "seen/not seen"ブール値にマッピングする配列を使用します。

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;
}

objects にも同じようなテクニックがあります。ダミーキーを取得し、それをarray1の各要素に対して "true"に設定してから、array2の要素でこのキーを探します。完了したらクリーンアップします。

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;
}

もちろん、キーが以前に表示されていないことを確認する必要があります。そうしないと、データが破壊されることになります。

4
tarulen
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;
}
4
Gabe

IE 9.0の "indexOf"、クロム、Firefox、オペラ、

    function intersection(a,b){
     var rs = [], x = a.length;
     while (x--) b.indexOf(a[x])!=-1 && rs.Push(a[x]);
     return rs.sort();
    }

intersection([1,2,3], [2,3,4,5]);
//Result:  [2,3]

list1.filter(n => list2.includes(n)) 以外に、これはおそらく最も単純なものです。

var list1 = ['bread', 'ice cream', 'cereals', 'strawberry', 'chocolate']
var list2 = ['bread', 'cherry', 'ice cream', 'oats']

function check_common(list1, list2){
        
        list3 = []
        for (let i=0; i<list1.length; i++){
                
                for (let j=0; j<list2.length; j++){  
                        if (list1[i] === list2[j]){
                                list3.Push(list1[i]);                           
                        }               
                }
                
        }
        return list3
        
}

check_common(list1, list2) // ["bread", "ice cream"]
3
Chris Lwin

私は私のために最もうまくいっていることに貢献するつもりです:

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;
};
}
3
Johan

地図を作成するための.reduceと交差点を見つけるための.filter.filter内のdeleteにより、2番目の配列を一意のセットであるかのように扱うことができます。

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;
  });
}

私はこのアプローチを考えるのはとても簡単だと思います。一定時間で実行されます。

2
Belden
'use strict'

// Example 1
function intersection(a1, a2) {
    return a1.filter(x => a2.indexOf(x) > -1)
}

// Example 2 (prototype function)
Array.prototype.intersection = function(arr) {
    return this.filter(x => arr.indexOf(x) > -1)
} 

const a1 = [1, 2, 3]
const a2 = [2, 3, 4, 5]

console.log(intersection(a1, a2))
console.log(a1.intersection(a2))
2
Vlad Bezden

ES2015による機能的アプローチ

機能的アプローチでは、副作用のない純粋な関数のみを使用することを検討しなければなりません。それぞれの機能は単一のジョブにのみ関係します。

これらの制限は、関係する機能の構成可能性および再利用可能性を高めます。

// small, reusable auxiliary functions

const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
const apply = f => x => f(x);


// intersection

const intersect = xs => ys => {
  const zs = createSet(ys);
  return filter(x => zs.has(x)
     ? true
     : false
  ) (xs);
};


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];


// run it

console.log( intersect(xs) (ys) );

ネイティブのSet型が使用されていることに注意してください。これはルックアップパフォーマンスに有利です。

重複を避ける

最初のArrayから繰り返し出現する項目は保存されますが、2番目のArrayは重複排除されます。これが望ましい動作かもしれません。一意の結果が必要な場合は、最初の引数にdedupeを適用するだけです。

// auxiliary functions

const apply = f => x => f(x);
const comp = f => g => x => f(g(x));
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// intersection

const intersect = xs => ys => {
  const zs = createSet(ys);
  return filter(x => zs.has(x)
     ? true
     : false
  ) (xs);
};


// de-duplication

const dedupe = comp(afrom) (createSet);


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];


// unique result

console.log( intersect(dedupe(xs)) (ys) );

任意の数のArrayの共通部分を計算します

任意の数のArrayの共通部分を計算したい場合は、intersectfoldlで構成してください。これが便利な関数です:

// auxiliary functions

const apply = f => x => f(x);
const uncurry = f => (x, y) => f(x) (y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);


// intersection

const intersect = xs => ys => {
  const zs = createSet(ys);
  return filter(x => zs.has(x)
     ? true
     : false
  ) (xs);
};


// intersection of an arbitrarily number of Arrays

const intersectn = (head, ...tail) => foldl(intersect) (head) (tail);


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];
const zs = [0,1,2,3,4,5,6];


// run

console.log( intersectn(xs, ys, zs) );
2
user6445533

簡単にするために:

// 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/Arrayプロトタイプの改ざん防止

欠点:

  • より高いメモリ使用量
  • より高いCPU使用率
  • 減量の理解が必要
  • データフローの理解が必要

これを3Dエンジンやカーネルの作業に使用することは望ましくありませんが、イベントベースのアプリケーションでこれを実行するのに問題がある場合は、デザインの問題が大きくなります。

2
Norguard
var listA = [1,2,3,4,5,6,7];
var listB = [2,4,6,8];

var result = listA.filter(itemA=> {
    return listB.some(itemB => itemB === itemA);
});
1
jcmordan

IndexOfを使用するのではなく、 Array.prototype.includes も使用できます。

function intersection(arr1, arr2) {
  return arr1.filter((ele => {
    return arr2.includes(ele);
  }));
}

console.log(intersection([1,2,3], [2,3,4,5]));
1
AZ_

これは underscore.js implementationです。

_.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;
};

ソース: http://underscorejs.org/docs/underscore.html#section-62

1
Dorian

ES6スタイルの簡単な方法。

const intersection = (a, b) => {
  const s = new Set(b);
  return a.filter(x => s.has(x));
};

例:

intersection([1, 2, 3], [4, 3, 2]); // [2, 3]
1
Alex Petre
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 ]
1
bekzat

交差する複数の配列を処理する必要がある場合

const intersect = (a, b, ...rest) => {
  if (rest.length === 0) return [...new Set(a)].filter(x => new Set(b).has(x));
  return intersect(a, intersect(b, ...rest));
};

console.log(intersect([1,2,3,4,5], [1,2], [1, 2, 3,4,5], [2, 10, 1])) // [1,2]
1
Belfordz

私はそれらのオブジェクトの特定の性質に基づいてオブジェクトの配列の交差を検出することさえできる交差関数を書きました。

例えば、

if arr1 = [{id: 10}, {id: 20}]
and arr2 =  [{id: 20}, {id: 25}]

idプロパティに基づいた交差が欲しい場合、出力は次のようになります。

[{id: 20}]

そのため、同じ機能(注:ES6コード)は次のとおりです。

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])

また、注意してください:この関数は最初の配列が一次配列であることを考慮して交差を見つけます、そしてそれゆえ交差の結果は一次配列のそれになるでしょう。

1
Mridul Meharia
var arrays = [
    [1, 2, 3],
    [2, 3, 4, 5]
]
function commonValue (...arr) {
    let res = arr[0].filter(function (x) {
        return arr.every((y) => y.includes(x))
    })
    return res;
}
commonValue(...arrays);
1
user1046987

受け入れられた答えを使用したいが、Internet Explorerのサポートが必要な場合は、矢印機能の簡略注釈を避けなければなりません。これはIEでも動作する編集済みのワンライナーです。

// accepted aswer: array1.filter(value => -1 !== array2.indexOf(value));
// IE-supported syntax:
array1.filter(function(value) { return -1 !== array2.indexOf(value) });
1
KjetilNordin

ECMA 2016以降、使用できるのは次のとおりです。

const intersection = (arr1, arr2) => arr1.filter(el => arr2.includes(el));

1
jota3

2番目の配列が常に set として扱われる場合は、2番目の配列の関数内で中間変数を宣言する必要はありません。

次の解決策は、両方の配列に現れる一意の値の配列を返します。

const intersection = (a, b) => {
  b = new Set(b); // recycling variable
  return [...new Set(a)].filter(e => b.has(e));
};

console.log(intersection([1, 2, 3, 1, 1], [1, 2, 4])); // Array [ 1, 2 ]
0
Grant Miller

SetArray#filterthisArgとして使用し、 Set#has をコールバックとして使用できます。

function intersection(a, b) {
    return a.filter(Set.prototype.has, new Set(b));
}

console.log(intersection([1, 2, 3], [2, 3, 4, 5]));
0
Nina Scholz

これがすべてのバージョンに役立つことを願っています。

function diffArray(arr1, arr2) {
  var newArr = [];

  var large = arr1.length>=arr2.length?arr1:arr2;
  var small = JSON.stringify(large) == JSON.stringify(arr1)?arr2:arr1;
  for(var i=0;i<large.length;i++){
    var copyExists = false; 
    for(var j =0;j<small.length;j++){
      if(large[i]==small[j]){
        copyExists= true;
        break;
      }
    }
    if(!copyExists)
      {
        newArr.Push(large[i]);
      }
  }

  for(var i=0;i<small.length;i++){
    var copyExists = false; 
    for(var j =0;j<large.length;j++){
      if(large[j]==small[i]){
        copyExists= true;
        break;
      }
    }
    if(!copyExists)
      {
        newArr.Push(small[i]);
      }
  }


  return newArr;
}
0
Shubham Pandey

1つの配列を使用してオブジェクトを作成し、2番目の配列をループ処理して値がキーとして存在するかどうかを確認します。

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;
}
0
sridhar reddy

配列がソートされている場合、これはO(n)で実行されます。nはmin(a.length、b.length)です。

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;
}
0
Dave Swanson

これは私が使っているとても素朴な実装です。それは非破壊的でありそしてまた全体を重複しないようにする。

Array.prototype.contains = function(elem) {
    return(this.indexOf(elem) > -1);
};

Array.prototype.intersect = function( array ) {
    // this is naive--could use some optimization
    var result = [];
    for ( var i = 0; i < this.length; i++ ) {
        if ( array.contains(this[i]) && !result.contains(this[i]) )
            result.Push( this[i] );
    }
    return result;
}
0
devios1

次のコードも重複を削除します。

       function intersect(x, y) {
            if (y.length > x.length) temp = y, y = x, x= temp;  
            return x.filter(function (e, i, c) {  
                  return c.indexOf(e) === i;
                 });
       }
0
Enayat Rajabi

コーヒースクリプト内のN個の配列の共通部分

getIntersection: (arrays) ->
    if not arrays.length
        return []
    a1 = arrays[0]
    for a2 in arrays.slice(1)
        a = (val for val in a1 when val in a2)
        a1 = a
    return a1.unique()
0
user1205224

Anonの優れた答えに基づいて、これは2つ以上の配列の共通部分を返します。

function arrayIntersect(arrayOfArrays)
{        
    var arrayCopy = arrayOfArrays.slice(),
        baseArray = arrayCopy.pop();

    return baseArray.filter(function(item) {
        return arrayCopy.every(function(itemList) {
            return itemList.indexOf(item) !== -1;
        });
    });
}
0

私はtarulenの答えを任意の数の配列で動作するように拡張しました。整数以外の値でも動作するはずです。

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;
}
0
gabe appleton

関数intersectionOfArrays(arr1、arr2){return arr1.filter((element)=> arr2.indexOf(element)!== -1).filter((element、pos、self)=> self.indexOf(element)== pos);}

0
Prakash Mandal