1097

JavaScript で 2 つの配列の違いを返す方法はありますか?

例えば:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

// need ["c", "d"]
4

79 に答える 79

2308

ES7 を使用するより良い方法があります。


交差点

 let intersection = arr1.filter(x => arr2.includes(x));

交点差ベン図

それ[1,2,3] [2,3]は をもたらすから[2,3]です。一方、 for[1,2,3] [2,3,5]は同じものを返します。


違い

let difference = arr1.filter(x => !arr2.includes(x));

右差ベン図

それ[1,2,3] [2,3]は をもたらすから[1]です。一方、 for[1,2,3] [2,3,5]は同じものを返します。


対称的な違いの場合、次のことができます。

let difference = arr1
                 .filter(x => !arr2.includes(x))
                 .concat(arr2.filter(x => !arr1.includes(x)));

対称差ベン図

このようにして、arr2 にはない arr1 のすべての要素を含む配列を取得し、その逆も同様です。

@Joshaven Potter が彼の回答で指摘したように、これを Array.prototype に追加して、次のように使用できます。

Array.prototype.diff = function(arr2) { return this.filter(x => !arr2.includes(x)); }
[1, 2, 3].diff([2, 3])
于 2015-10-09T09:33:10.723 に答える
948

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

//////////////
// Examples //
//////////////

const dif1 = [1,2,3,4,5,6].diff( [3,4,5] );  
console.log(dif1); // => [1, 2, 6]


const dif2 = ["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);  
console.log(dif2); // => ["test5", "test6"]

.indexOf().filter()は IE9 より前では使用できません。

于 2010-10-26T18:34:42.387 に答える
319

この回答は2009年に書かれたものなので、少し古くなっています。また、問題を理解するための教育的です。今日使用する最善の解決策は

let difference = arr1.filter(x => !arr2.includes(x));

(ここに他の著者へのクレジット)

通常の配列を比較していると思います。そうでない場合は、 forループをfor .. inループに変更する必要があります。

function arr_diff (a1, a2) {

    var a = [], diff = [];

    for (var i = 0; i < a1.length; i++) {
        a[a1[i]] = true;
    }

    for (var i = 0; i < a2.length; i++) {
        if (a[a2[i]]) {
            delete a[a2[i]];
        } else {
            a[a2[i]] = true;
        }
    }

    for (var k in a) {
        diff.push(k);
    }

    return diff;
}

console.log(arr_diff(['a', 'b'], ['a', 'b', 'c', 'd']));
console.log(arr_diff("abcd", "abcde"));
console.log(arr_diff("zxc", "zxc"));

于 2009-07-27T11:20:33.540 に答える
311

これは、jQuery を使用して、探している結果を正確に取得する最も簡単な方法です。

var diff = $(old_array).not(new_array).get();

diff含まれていたものが含まれold_arrayていないnew_array

于 2013-03-13T12:57:04.890 に答える
174

Underscore の difference メソッド(またはそのドロップイン置換であるLo-Dash ) もこれを行うことができます。

(R)eturns the values from array that are not present in the other arrays

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

Underscore 関数と同様に、よりオブジェクト指向のスタイルで使用することもできます。

_([1, 2, 3, 4, 5]).difference([5, 2, 10]);
于 2012-07-05T22:44:52.087 に答える
89

プレーン JavaScript

「違い」には2つの解釈があります。どれがいいか選ばせてもらいます。あなたが持っているとしましょう:

var a1 = ['a', 'b'     ];
var a2 = [     'b', 'c'];
  1. を取得する場合は['a']、次の関数を使用します。

    function difference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      return result;
    }
    
  2. 取得したい場合(または のいずれかに['a', 'c']含まれるすべての要素で、両方には含まれない - いわゆる対称差)、次の関数を使用します。 a1a2

    function symmetricDifference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      for (i = 0; i < a2.length; i++) {
        if (a1.indexOf(a2[i]) === -1) {
          result.push(a2[i]);
        }
      }
      return result;
    }
    

ロダッシュ/アンダースコア

lodash を使用している場合は、_.difference(a1, a2)(上記のケース 1) または_.xor(a1, a2)(ケース 2) を使用できます。

Underscore.js を使用している場合は_.difference(a1, a2)、ケース 1 の関数を使用できます。

非常に大きな配列用の ES6 セット

上記のコードは、すべてのブラウザーで機能します。ただし、約 10,000 項目を超える大規模な配列の場合、O(n²) の複雑さがあるため、非常に遅くなります。多くの最新のブラウザーでは、ES6Setオブジェクトを利用して処理を高速化できます。Lodash はSet、利用可能な場合に自動的に使用します。lodash を使用していない場合は、Axel Rauschmayer のブログ投稿に触発された次の実装を使用してください。

function difference(a1, a2) {
  var a2Set = new Set(a2);
  return a1.filter(function(x) { return !a2Set.has(x); });
}

function symmetricDifference(a1, a2) {
  return difference(a1, a2).concat(difference(a2, a1));
}

ノート

-0、+0、NaN、またはスパース配列に関心がある場合、すべての例の動作は驚くべきものであるか、自明ではないかもしれません。(ほとんどの用途では、これは問題ではありません。)

于 2015-05-17T16:01:29.743 に答える
53

この場合、セットを使用できます。この種の操作 (ユニオン、インターセクション、ディファレンス) に最適化されています。

重複が許可されたら、ケースに適用されることを確認してください。

var a = new JS.Set([1,2,3,4,5,6,7,8,9]);
var b = new JS.Set([2,4,6,8]);

a.difference(b)
// -> Set{1,3,5,7,9}
于 2009-07-27T10:43:55.877 に答える
33
function diff(a1, a2) {
  return a1.concat(a2).filter(function(val, index, arr){
    return arr.indexOf(val) === arr.lastIndexOf(val);
  });
}

両方の配列をマージします。一意の値は 1 回だけ表示されるため、indexOf() は lastIndexOf() と同じになります。

于 2015-06-30T14:33:56.300 に答える
28

セットとスプラット演算子を備えた ES6 の登場により (現時点では Firefox でのみ動作します。互換性テーブルを確認してください)、次のワンライナーを記述できます。

var a = ['a', 'b', 'c', 'd'];
var b = ['a', 'b'];
var b1 = new Set(b);
var difference = [...new Set(a.filter(x => !b1.has(x)))];

になり[ "c", "d" ]ます。

于 2015-01-17T07:15:09.227 に答える
18

ある配列を別の配列から減算するには、以下のスニペットを使用するだけです。

var a1 = ['1','2','3','4','6'];
var a2 = ['3','4','5'];

var items = new Array();

items = jQuery.grep(a1,function (item) {
    return jQuery.inArray(item, a2) < 0;
});

2番目の配列には存在しない最初の配列のアイテムである ['1,'2','6'] を返します。

したがって、問題のサンプルによると、次のコードが正確な解決策です。

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var _array = new Array();

_array = jQuery.grep(array2, function (item) {
     return jQuery.inArray(item, array1) < 0;
});
于 2011-11-21T11:26:17.967 に答える
15

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

difference2 つの配列間の を計算することは、Set操作の 1 つです。Setこの用語は、検索速度を上げるためにネイティブ型を使用する必要があることをすでに示しています。とにかく、2 つのセットの差を計算すると、3 つの順列があります。

[+left difference] [-intersection] [-right difference]
[-left difference] [-intersection] [+right difference]
[+left difference] [-intersection] [+right difference]

これらの順列を反映する機能的なソリューションを次に示します。

difference

// small, reusable auxiliary functions

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


// left difference

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


// mock data

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


// run the computation

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

difference

differencer些細なことです。それは単にdifferencel議論が反転しているだけです。便宜上、関数を書くことができます: const differencer = flip(differencel). それで全部です!

対称difference:

左右のものがあるので、対称の実装もdifference簡単になります。

// small, reusable auxiliary functions

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


// left difference

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


// symmetric difference

const difference = ys => xs =>
 concat(differencel(xs) (ys)) (flip(differencel) (xs) (ys));

// mock data

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


// run the computation

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

この例は、関数型プログラミングが何を意味するのかを理解するための良い出発点だと思います。

さまざまな方法で接続できるビルディング ブロックを使用したプログラミング。

于 2016-10-11T16:00:30.253 に答える
12

を使用したソリューションindexOf()は、小さな配列には問題ありませんが、配列が長くなるにつれて、アルゴリズムのパフォーマンスは に近づきO(n^2)ます。オブジェクトを連想配列として使用して配列エントリをキーとして格納することにより、非常に大きな配列のパフォーマンスを向上させるソリューションを次に示します。また、重複するエントリを自動的に排除しますが、文字列値 (または文字列として安全に保存できる値) でのみ機能します。

function arrayDiff(a1, a2) {
  var o1={}, o2={}, diff=[], i, len, k;
  for (i=0, len=a1.length; i<len; i++) { o1[a1[i]] = true; }
  for (i=0, len=a2.length; i<len; i++) { o2[a2[i]] = true; }
  for (k in o1) { if (!(k in o2)) { diff.push(k); } }
  for (k in o2) { if (!(k in o1)) { diff.push(k); } }
  return diff;
}

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
arrayDiff(a1, a2); // => ['c', 'd']
arrayDiff(a2, a1); // => ['c', 'd']
于 2012-05-15T15:22:23.053 に答える
10

Joshaven Potterによる上記の回答は素晴らしいです。ただし、配列 C にない要素を配列 B に返しますが、その逆は返しません。たとえば、 if var a=[1,2,3,4,5,6].diff( [3,4,5,7]);then it will output: ==> [1,2,6], but not [1,2,6,7] , これが 2 つの実際の違いです。上記のポッターのコードを引き続き使用できますが、逆方向に比較をやり直すだけです。

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return !(a.indexOf(i) > -1);});
};

////////////////////  
// Examples  
////////////////////

var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
var b=[3,4,5,7].diff([1,2,3,4,5,6]);
var c=a.concat(b);
console.log(c);

これにより、次のように出力されます。[ 1, 2, 6, 7 ]

于 2012-09-20T18:27:32.293 に答える
7
Array.prototype.difference = function(e) {
    return this.filter(function(i) {return e.indexOf(i) < 0;});
};

eg:- 

[1,2,3,4,5,6,7].difference( [3,4,5] );  
 => [1, 2, 6 , 7]
于 2015-07-07T14:55:28.360 に答える
6

これはどう:

Array.prototype.contains = function(needle){
  for (var i=0; i<this.length; i++)
    if (this[i] == needle) return true;

  return false;
} 

Array.prototype.diff = function(compare) {
    return this.filter(function(elem) {return !compare.contains(elem);})
}

var a = new Array(1,4,7, 9);
var b = new Array(4, 8, 7);
alert(a.diff(b));

したがって、このようにしarray1.diff(array2)て、それらの違いを取得することができます(ただし、アルゴリズムの時間計算量はひどいです-O(array1.length x array2.length)と思います)

于 2010-08-05T21:10:26.163 に答える
4

http://phrogz.net/JS/ArraySetMath.jsを使用すると、次のことができます。

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var array3 = array2.subtract( array1 );
// ["test5", "test6"]

var array4 = array1.exclusion( array2 );
// ["test5", "test6"]
于 2011-01-25T18:21:10.997 に答える
4
  • 純粋な JavaScript ソリューション (ライブラリなし)
  • 古いブラウザーと互換性があります (使用しませんfilter) 。
  • O(n^2)
  • fn配列アイテムの比較方法を指定できるオプションのコールバック パラメータ

function diff(a, b, fn){
    var max = Math.max(a.length, b.length);
        d = [];
    fn = typeof fn === 'function' ? fn : false
    for(var i=0; i < max; i++){
        var ac = i < a.length ? a[i] : undefined
            bc = i < b.length ? b[i] : undefined;
        for(var k=0; k < max; k++){
            ac = ac === undefined || (k < b.length && (fn ? fn(ac, b[k]) : ac == b[k])) ? undefined : ac;
            bc = bc === undefined || (k < a.length && (fn ? fn(bc, a[k]) : bc == a[k])) ? undefined : bc;
            if(ac == undefined && bc == undefined) break;
        }
        ac !== undefined && d.push(ac);
        bc !== undefined && d.push(bc);
    }
    return d;
}

alert(
    "Test 1: " + 
    diff(
        [1, 2, 3, 4],
        [1, 4, 5, 6, 7]
      ).join(', ') +
    "\nTest 2: " +
    diff(
        [{id:'a',toString:function(){return this.id}},{id:'b',toString:function(){return this.id}},{id:'c',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        [{id:'a',toString:function(){return this.id}},{id:'e',toString:function(){return this.id}},{id:'f',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        function(a, b){ return a.id == b.id; }
    ).join(', ')
);

于 2014-09-17T19:57:48.113 に答える
3

古い配列と新しい配列を受け取り、追加されたアイテムの配列と削除されたアイテムの配列を提供する同様の関数が必要でした.

ここで提案されたソリューションを試すことができます: http://jsbin.com/osewu3/12

誰でもそのアルゴリズムの問​​題/改善を見ることができますか? ありがとう!

コード リスト:

function diff(o, n) {
  // deal with empty lists
  if (o == undefined) o = [];
  if (n == undefined) n = [];

  // sort both arrays (or this won't work)
  o.sort(); n.sort();

  // don't compare if either list is empty
  if (o.length == 0 || n.length == 0) return {added: n, removed: o};

  // declare temporary variables
  var op = 0; var np = 0;
  var a = []; var r = [];

  // compare arrays and add to add or remove lists
  while (op < o.length && np < n.length) {
      if (o[op] < n[np]) {
          // push to diff?
          r.push(o[op]);
          op++;
      }
      else if (o[op] > n[np]) {
          // push to diff?
          a.push(n[np]);
          np++;
      }
      else {
          op++;np++;
      }
  }

  // add remaining items
  if( np < n.length )
    a = a.concat(n.slice(np, n.length));
  if( op < o.length )
    r = r.concat(o.slice(op, o.length));

  return {added: a, removed: r}; 
}
于 2010-08-13T12:07:33.277 に答える
3

これは機能しています。基本的に2つの配列をマージし、重複を探し、重複していないものを新しい配列にプッシュします。これが違いです。

function diff(arr1, arr2) {
  var newArr = [];
  var arr = arr1.concat(arr2);
  
  for (var i in arr){
    var f = arr[i];
    var t = 0;
    for (j=0; j<arr.length; j++){
      if(arr[j] === f){
        t++; 
        }
    }
    if (t === 1){
      newArr.push(f);
        }
  } 
  return newArr;
}

于 2015-08-01T10:33:24.383 に答える
3

underscore.js を使用できます: http://underscorejs.org/#intersection

array のメソッドが必要です:

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]
于 2012-09-27T08:55:43.443 に答える
2

別のライブラリを使用しない簡単な答えを探していたのですが、ここでは言及されていないと思う自分の答えを思いつきました。それがどれほど効率的かはわかりませんが、機能します。

    function find_diff(arr1, arr2) {
      diff = [];
      joined = arr1.concat(arr2);
      for( i = 0; i <= joined.length; i++ ) {
        current = joined[i];
        if( joined.indexOf(current) == joined.lastIndexOf(current) ) {
          diff.push(current);
        }
      }
      return diff;
    }

私のコードでは、複製も削除する必要がありますが、それが常に好ましいとは限りません。

主な欠点は、すでに拒否されている多くのオプションを比較している可能性があることだと思います。

于 2011-07-16T04:22:59.020 に答える
2

最良の答えのための少しの修正

function arr_diff(a1, a2)
{
  var a=[], diff=[];
  for(var i=0;i<a1.length;i++)
    a[a1[i]]=a1[i];
  for(var i=0;i<a2.length;i++)
    if(a[a2[i]]) delete a[a2[i]];
    else a[a2[i]]=a2[i];
  for(var k in a)
   diff.push(a[k]);
  return diff;
}

これは、現在のタイプの要素を考慮に入れます。b / c a [a1 [i]]を作成すると、値が元の値から文字列に変換されるため、実際の値が失われます。

于 2012-04-18T06:43:40.293 に答える
2

すべての値を単純に比較し、繰り返さない値で配列を返します。

var main = [9, '$', 'x', 'r', 3, 'A', '#', 0, 1];

var arr0 = ['Z', 9, 'e', '$', 'r'];
var arr1 = ['x', 'r', 3, 'A', '#'];
var arr2 = ['m', '#', 'a', 0, 'r'];
var arr3 = ['$', 1, 'n', '!', 'A'];


Array.prototype.diff = function(arrays) {
    var items = [].concat.apply(this, arguments);
    var diff = [].slice.call(items), i, l, x, pos;

    // go through all items
    for (x = 0, i = 0, l = items.length; i < l; x = 0, i++) {
        // find all positions
        while ((pos = diff.indexOf(items[i])) > -1) {
            // remove item + increase found count
            diff.splice(pos, 1) && x++;
        }
        // if item was found just once, put it back
        if (x === 1) diff.push(items[i]);
    }
    // get all not duplicated items
    return diff;
};

main.diff(arr0, arr1, arr2, arr3).join(''); // returns "Zeman!"

[].diff(main, arr0, arr1, arr2, arr3).join(''); // returns "Zeman!"
于 2015-10-11T07:23:28.667 に答える
2

これは、Thinker によって受け入れられた回答に触発されたものですが、Thinker の回答は、配列がセットであると想定しているようです。配列が次の場合、バラバラになり[ "1", "2" ]ます[ "1", "1", "2", "2" ]

これらの配列の違いは[ "1", "2" ]. 次のソリューションは O(n*n) なので理想的ではありませんが、配列が大きい場合は、Thinker のソリューションよりもメモリの利点があります。

そもそもセットを扱っている場合は、Thinker のソリューションの方が断然優れています。フィルターにアクセスできる新しいバージョンの Javascript を使用している場合は、それらも使用する必要があります。これは、セットを扱っておらず、古いバージョンの JavaScript を使用している (何らかの理由で) 人のみを対象としています...

if (!Array.prototype.diff) { 
    Array.prototype.diff = function (array) {
        // if the other array is a falsy value, return a copy of this array
        if ((!array) || (!Array.prototype.isPrototypeOf(array))) { 
            return this.slice(0);
        }

        var diff = [];
        var original = this.slice(0);

        for(var i=0; i < array.length; ++i) {
            var index = original.indexOf(array[i]);
            if (index > -1) { 
                original.splice(index, 1);
            } else { 
                diff.push(array[i]);
            }
        }

        for (var i=0; i < original.length; ++i) {
            diff.push(original[i]);
        }
        return diff;
    }
}   
于 2014-01-30T17:19:27.443 に答える
2
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
var diff = [];
for (var i in a2) {
   var found = false;
   for (var j in a1) {
      if (a2[i] === a1[j]) found = true;
   }
   if (found === false) diff.push(a2[i]);
}

それは簡単です。オブジェクトの 1 つのプロパティをチェックして、オブジェクトでも使用できます。お気に入り、

if (a2[i].id === a1[j].id) found = true;
于 2018-12-16T19:45:42.330 に答える
2

それを試してみてください。

var first = [ 1, 2, 3, 4, 5 ];
    var second = [ 4, 5, 6 ];
     
    var difference = first.filter(x => second.indexOf(x) === -1);
    console.log(difference);


Output: [ 1, 2, 3]

var first = [ 1, 2, 3, 4, 5 ];
    var second = [ 4, 5, 6 ];
     
    var difference = first.filter(x => second.indexOf(x) === -1);
    console.log(difference);

于 2021-05-24T05:41:02.520 に答える
2
var result = [];
var arr1 = [1,2,3,4];
var arr2 = [2,3];
arr1.forEach(function(el, idx) {
    function unEqual(element, index, array) {
        var a = el;
        return (element!=a);
    }
    if (arr2.every(unEqual)) {
        result.push(el);
    };
});
alert(result);
于 2013-09-15T17:06:02.900 に答える
1

ある配列から別の配列を減算したい人に応えて...

1000要素しか言わない場合は、これを試してください...

新しい変数をセットアップして Array01 を複製し、それを Array03 と呼びます。

ここで、バブル ソート アルゴリズムを使用して Array01 の要素を Array02 と比較し、一致するものが見つかったら、Array03 に対して次の操作を行います...

 if (Array01[x]==Array02[y]) {Array03.splice(x,1);}

注意: バブル ソートのネストされたループを台無しにしないように、Array01 の代わりに Array03 を変更しています。

最後に、単純な割り当てを使用して Array03 の内容を Array01 にコピーすれば完了です。

于 2011-07-20T12:20:13.013 に答える
1

サミュエル: 「私のコードでは重複を取り除く必要がありますが、それが常に好まれるとは限りません。主な欠点は、既に拒否された多くのオプションを比較する可能性があることです。」

2 つのリスト、配列などを比較し、要素が 1000 未満の場合、3GL 世界の業界標準は、重複を回避するバブル ソートを使用することです。

コードは次のようになります... (テストされていませんが、動作するはずです)

var Array01=new Array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P');
var Array02=new Array('X','B','F','W','Z','X','J','P','P','O','E','N','Q');
var Array03=Array01;

for(x=1; x<Array02.length; x++) {
 for(y=0; y<Array01.length-1; y++) {
  if (Array01[y]==Array02[x]) {Array03.splice(y,1);}}}

Array01=Array03;

出力をテストするには...

for(y=0; y<Array01.length; y++) {document.write(Array01[y])}
于 2011-07-20T16:33:15.557 に答える
1

ただ考えている...挑戦のために;-)これはうまくいくでしょうか...(文字列、数値などの基本的な配列の場合)ネストされた配列はありません

function diffArrays(arr1, arr2, returnUnion){
  var ret = [];
  var test = {};
  var bigArray, smallArray, key;
  if(arr1.length >= arr2.length){
    bigArray = arr1;
    smallArray = arr2;
  } else {
    bigArray = arr2;
    smallArray = arr1;
  }
  for(var i=0;i<bigArray.length;i++){
    key = bigArray[i];
    test[key] = true;
  }
  if(!returnUnion){
    //diffing
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = null;
      }
    }
  } else {
    //union
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = true;
      }
    }
  }
  for(var i in test){
    ret.push(i);
  }
  return ret;
}

array1 = "test1", "test2","test3", "test4", "test7"
array2 = "test1", "test2","test3","test4", "test5", "test6"
diffArray = diffArrays(array1, array2);
//returns ["test5","test6","test7"]

diffArray = diffArrays(array1, array2, true);
//returns ["test1", "test2","test3","test4", "test5", "test6","test7"]

並べ替えは上記のようにはならない可能性が高いことに注意してください...ただし、必要に応じて、配列で .sort() を呼び出して並べ替えます。

于 2009-07-27T11:11:13.810 に答える
1

hasOwnProperty を使用しない場合、要素が正しくありません。例えば:

[1,2,3].diff([1,2]); //Return ["3", "remove", "diff"] This is the wrong version

私のバージョン:

Array.prototype.diff = function(array2)
  {
    var a = [],
        diff = [],
        array1 = this || [];

    for (var i = 0; i < array1.length; i++) {
      a[array1[i]] = true;
    }
    for (var i = 0; i < array2.length; i++) {
      if (a[array2[i]]) {
        delete a[array2[i]];
      } else {
        a[array2[i]] = true;
      }
    }

    for (var k in a) {
      if (!a.hasOwnProperty(k)){
        continue;
      }
      diff.push(k);
    }

    return diff;
  }
于 2013-05-29T10:25:40.320 に答える
1

CoffeeScript のバージョン:

diff = (val for val in array1 when val not in array2)
于 2015-03-20T16:33:54.577 に答える
0

私がここで読んでいる答えには多くの問題があり、実際のプログラミングアプリケーションでは価値が限られています。

何よりもまず、配列内の2つのアイテムが「等しい」ことの意味を制御する方法が必要になります。IDなどに基づいてオブジェクトの配列を更新するかどうかを判断しようとしている場合、===の比較ではうまくいきません。率直に言って、これはおそらく最も可能性の高いシナリオの1つです。差分関数。また、===演算子と比較できるもの、つまり文字列、intなどの配列に制限されますが、これは大人にはほとんど受け入れられません。

次に、diff操作の3つの状態の結果があります。

  1. 最初の配列にはあるが2番目の配列にはない要素
  2. 両方の配列に共通する要素
  3. 2番目の配列にはあるが、最初の配列にはない要素

これは、2つ以上のループが必要であることを意味すると思いますが、誰かがそれを1つに減らす方法を知っていれば、汚いトリックを受け入れることができます。

これが私が一緒に考え出したものです。古いバージョンのMicroshaftブラウザでは機能しないことを絶対に気にしないことを強調したいと思います。IEのような劣ったコーディング環境で作業している場合は、行き詰まっている不十分な制限の範囲内で動作するように変更するのはあなた次第です。

Array.defaultValueComparison = function(a, b) {
    return (a === b);
};

Array.prototype.diff = function(arr, fnCompare) {

    // validate params

    if (!(arr instanceof Array))
        arr = [arr];

    fnCompare = fnCompare || Array.defaultValueComparison;

    var original = this, exists, storage, 
        result = { common: [], removed: [], inserted: [] };

    original.forEach(function(existingItem) {

        // Finds common elements and elements that 
        // do not exist in the original array

        exists = arr.some(function(newItem) {
            return fnCompare(existingItem, newItem);
        });

        storage = (exists) ? result.common : result.removed;
        storage.push(existingItem);

    });

    arr.forEach(function(newItem) {

        exists = original.some(function(existingItem) {
            return fnCompare(existingItem, newItem);
        });

        if (!exists)
            result.inserted.push(newItem);

    });

    return result;

};
于 2012-05-15T14:58:54.423 に答える
0
const difference = function (baseArray, arrayToCampare, callback = (a, b) => a!== b) {
  if (!(arrayToCampare instanceof Array)) {
    return baseArray;
  }
  return baseArray.filter(baseEl =>
    arrayToCampare.every(compareEl => callback(baseEl, compareEl)));
}
于 2017-01-12T14:06:44.657 に答える
0

確実にするために文字列をトリミングするだけです....スペースは差分に影響しません

function arr_diff(a1, a2) {
    var a=[], diff=[];
    for(var i=0;i<a1.length;i++)
        a[a1[i]]=true;
    for(var i=0;i<a2.length;i++)
        if(a[a2[i].trim()]) delete a[a2[i].trim()];
    else a[a2[i].trim()]=true;
    for(var k in a)
        diff.push(k);
    return diff;
}
于 2014-03-07T19:09:56.337 に答える
0

データ:

var new_storage = JSON.parse('[{"id_order":"0003"},{"id_order":"0004"},{"id_order":"0006"}]');

var old_storage = JSON.parse('[{"id_order":"0001"},{"id_order":"0002"},{"id_order":"0003"},{"id_order":"0004"},{"id_order":"0005"}]');

フィルターの使用:

var diff = new_storage
.filter(x => {if(!(old_storage.filter(y => y.id_order==x.id_order)).length){return x}})
    .concat(old_storage
    .filter(x => {if(!(new_storage.filter(y => y.id_order==x.id_order)).length){return x}})
                       ) 

console.log(JSON.stringify(diff))

2 つの配列の結果の違い

[{"id_order":"0006"},{"id_order":"0001"},{"id_order":"0002"},{"id_order":"0005"}]
于 2016-10-13T23:41:11.317 に答える
0

これが私が使用するものです:

var newArr = a1.filter(function(elem) {
            return a2.indexOf(elem) === -1;
        }).concat( a2.filter(function(elem) {
            return a1.indexOf(elem) === -1;
        }));
console.log(newArr);

またはこれ

var newArr = a1.concat(a2);
        function check(item) {
            if (a1.indexOf(item) === -1 || a2.indexOf(item) === -1) {
                return item;
            }
        }
        return newArr.filter(check);
于 2016-01-16T15:05:18.397 に答える
0
var arrayDifference = function(arr1, arr2){
  if(arr1 && arr1.length){
    if(arr2 && arr2.length > 0){
      for (var i=0, itemIndex; i<arr2.length; i++){
        itemIndex = arr1.indexOf(arr2[i]);
        if(itemIndex !== -1){
          arr1.splice(itemIndex, 1);
        }
      }
    }
    return arr1;
  }
  return [];
};

arrayDifference([1,2,3,4,5], [1,5,6]);
于 2016-05-24T07:33:49.163 に答える
0

配列にオブジェクトが含まれている場合、属性を比較したい場合は少し難しくなります。

幸いなことに、 and を使用するとlodash、これが非常に簡単_containsになり_.pluckます。

var list1 = [{id: 1},{id: 2}];
var list1 = [{id: 1},{id: 2}, {id: 3}];

//es6
var results = list2.filter(item => {
  return !_.contains(_.pluck(list1, 'id'), item.id);
});

//es5
var results = list2.filter(function(item){
  return !_.contains(_.pluck(list1, 'id'), item.id);
});

//results contains [{id: 3}]
于 2015-06-15T08:19:17.410 に答える
0

この質問は古いですが、依然としてJavaScript 配列減算のトップ ヒットであるため、使用しているソリューションを追加したいと考えました。これは、次の場合に適しています。

var a1 = [1,2,2,3]
var a2 = [1,2]
//result = [2,3]

次の方法では、目的の結果が得られます。

function arrayDifference(minuend, subtrahend) {
  for (var i = 0; i < minuend.length; i++) {
    var j = subtrahend.indexOf(minuend[i])
    if (j != -1) {
      minuend.splice(i, 1);
      subtrahend.splice(j, 1);
    }
  }
  return minuend;
}

関数には、被減数に存在しない減数からの値が含まれないことに注意してください。

var a1 = [1,2,3]
var a2 = [2,3,4]
//result = [1]
于 2014-01-14T22:02:37.863 に答える
0

これは、オブジェクトを使用してハッシュを格納するわずかに変更されたバージョンで、配列内の文字列だけでなく数値も処理できます。

function arrDiff(a, b) {
  const hash = {};
  a.forEach(n => { hash[n] = n; });
  b.forEach(n => {
    if (hash[n]) {
      delete hash[n];
    } else {
      hash[n] = n;
    }
  });
  return Object.values(hash);
}
于 2020-09-10T04:52:19.337 に答える
-1

私はこの質問に陥ります。これは、2 つの単純な配列の差を取得することでした。

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

// need ["c", "d"]

基本的な for ループを使用しない理由がわかりません。

for(var i=0; i < a1.length; i++) {
  for(var j=0; j < a2.length; j++) {
    if(a1[i] == a2[j]) {
      a2.splice(j, 1);
    }
  }
}

必要な["c", "d"]

[編集] すぐ上に提案され、遅れて見られました。

とにかく、この単純な解決策を避ける正当な理由はありますか?

于 2013-06-14T17:54:10.170 に答える
-2

文字列オブジェクト型へのキャスト:

[1, 1].toString() === [1, 1].toString(); // true
于 2015-10-04T10:18:52.017 に答える