JavaScript에서 두 배열의 차이를 반환하는 방법이 있습니까?
예를 들면 다음과 같습니다.
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
O(a1.length x log(a2.length))
이 성능은 JavaScript에서 가능합니까?
JavaScript에서 두 배열의 차이를 반환하는 방법이 있습니까?
예를 들면 다음과 같습니다.
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
O(a1.length x log(a2.length))
이 성능은 JavaScript에서 가능합니까?
답변:
일반 배열을 비교한다고 가정합니다. 그렇지 않은 경우 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"));
이전 버전과의 호환성에 관심이없는 경우 더 나은 솔루션은 필터를 사용하는 것입니다. 그러나 여전히이 솔루션은 작동합니다.
var a1 = ['a', 'b'];
과 var a2 = ['a', 'b', 'c', 'd', 'b'];
, 그것은 잘못된 답을 반환합니다 즉, ['c', 'd', 'b']
대신 ['c', 'd']
.
function diff2(a, b) { var i, la = a.length, lb = b.length, res = []; if (!la) return b; else if (!lb) return a; for (i = 0; i < la; i++) { if (b.indexOf(a[i]) === -1) res.push(a[i]); } for (i = 0; i < lb; i++) { if (a.indexOf(b[i]) === -1) res.push(b[i]); } return res; }
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]
는 같은 것을 반환합니다.
A에 대한 대칭 적 차이 , 당신은 할 수 있습니다 :
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])
< 0
대신 확인하는 것이 좋습니다== -1
Array
차이를 계산 하는 것은 이른바 set operation
, / Set
보다 빠르다 . 간단히 말해, 솔루션은 매우 비효율적이며 다소 느립니다. indexOf
includes
Set
값은 고유해야합니다.
Array.includes()
대신 ES6의 ES7 기능은? (1) (2) — 계속하려면 ES6을 사용하여 Array.some()
예를 들어 let intersection = aArray.filter(a => bArray.some(b => a === b))
no?
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;});
};
////////////////////
// Examples
////////////////////
[1,2,3,4,5,6].diff( [3,4,5] );
// => [1, 2, 6]
["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);
// => ["test5", "test6"]
참고 indexOf 및 필터는 ie9 이전에는 사용할 수 없습니다.
[1,2,3].diff([3,4,5])
반환 되어 원래 질문의 문제를 해결하지 못합니다. [1,2]
[1,2,4,5]
이것은 jQuery를 사용하여 원하는 결과를 정확하게 얻는 가장 쉬운 방법입니다.
var diff = $(old_array).not(new_array).get();
diff
지금에 무슨 포함 old_array
그게 아닙니다new_array
.not
배열과 함께 사용하면 jQuery는 .grep()
배열을 필터링하기 위해 내장 유틸리티 를 사용합니다. 이 변화를 볼 수 없습니다.
Underscore (또는 드롭 인 대체 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]);
"차이"에 대한 두 가지 가능한 해석이 있습니다. 원하는 것을 고를 수 있도록하겠습니다. 당신이 가지고 있다고 :
var a1 = ['a', 'b' ];
var a2 = [ 'b', 'c'];
을 얻으려면 ['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;
}
['a', 'c']
( 또는 소위 대칭 차이 라는 둘 중 하나 a1
또는에 포함 된 모든 요소) 를 얻으려면 이 함수를 사용하십시오.a2
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 기능을 .
위의 코드는 모든 브라우저에서 작동합니다. 그러나 약 10,000 개가 넘는 항목의 대형 배열의 경우 O (n²) 복잡도를 갖기 때문에 상당히 느려집니다. 많은 최신 브라우저에서 ES6 Set
객체를 활용 하여 작업 속도를 높일 수 있습니다. 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 또는 희소 배열 을 신경 쓰면 모든 예제의 동작이 놀랍거나 분명하지 않을 수 있습니다. (대부분의 경우, 이것은 중요하지 않습니다.)
대칭적인 차이 를 얻으려면 두 가지 방법으로 (또는 여러 배열의 경우 모든 방법으로) 배열을 비교해야합니다.
// diff between just two arrays:
function arrayDiff(a, b) {
return [
...a.filter(x => !b.includes(x)),
...b.filter(x => !a.includes(x))
];
}
// diff between multiple arrays:
function arrayDiff(...arrays) {
return [].concat(...arrays.map( (arr, i) => {
const others = arrays.slice(0);
others.splice(i, 1);
const unique = [...new Set([].concat(...others))];
return arr.filter(x => !unique.includes(x));
}));
}
// diff between just two arrays:
function arrayDiff(a, b) {
return [
...a.filter(x => b.indexOf(x) === -1),
...b.filter(x => a.indexOf(x) === -1)
];
}
// diff between multiple arrays:
function arrayDiff(...arrays) {
return [].concat(...arrays.map( (arr, i) => {
const others = arrays.slice(0);
others.splice(i, 1);
const unique = [...new Set([].concat(...others))];
return arr.filter(x => unique.indexOf(x) === -1);
}));
}
// diff between just two arrays:
function arrayDiff(a, b) {
var arrays = Array.prototype.slice.call(arguments);
var diff = [];
arrays.forEach(function(arr, i) {
var other = i === 1 ? a : b;
arr.forEach(function(x) {
if (other.indexOf(x) === -1) {
diff.push(x);
}
});
})
return diff;
}
// diff between multiple arrays:
function arrayDiff() {
var arrays = Array.prototype.slice.call(arguments);
var diff = [];
arrays.forEach(function(arr, i) {
var others = arrays.slice(0);
others.splice(i, 1);
var otherValues = Array.prototype.concat.apply([], others);
var unique = otherValues.filter(function (x, j) {
return otherValues.indexOf(x) === j;
});
diff = diff.concat(arr.filter(x => unique.indexOf(x) === -1));
});
return diff;
}
예:
// diff between two arrays:
const a = ['a', 'd', 'e'];
const b = ['a', 'b', 'c', 'd'];
arrayDiff(a, b); // (3) ["e", "b", "c"]
// diff between multiple arrays
const a = ['b', 'c', 'd', 'e', 'g'];
const b = ['a', 'b'];
const c = ['a', 'e', 'f'];
arrayDiff(a, b, c); // (4) ["c", "d", "g", "f"]
function arrayDiffByKey(key, ...arrays) {
return [].concat(...arrays.map( (arr, i) => {
const others = arrays.slice(0);
others.splice(i, 1);
const unique = [...new Set([].concat(...others))];
return arr.filter( x =>
!unique.some(y => x[key] === y[key])
);
}));
}
예:
const a = [{k:1}, {k:2}, {k:3}];
const b = [{k:1}, {k:4}, {k:5}, {k:6}];
const c = [{k:3}, {k:5}, {k:7}];
arrayDiffByKey('k', a, b, c); // (4) [{k:2}, {k:4}, {k:6}, {k:7}]
ES6의 깔끔한 접근 방식은 다음과 같습니다.
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
a2.filter(d => !a1.includes(d)) // gives ["c", "d"]
a2.filter(d => a1.includes(d)) // gives ["a", "b"]
[ ...a2.filter(d => !a1.includes(d)),
...a1.filter(d => !a2.includes(d)) ]
a1 = ['a', 'b', 'e']
: 전자가 추출되지 않습니다.
이 경우 Set 을 사용할 수 있습니다 . 이런 종류의 작업 (유니온, 교차, 차이)에 최적화되어 있습니다.
중복이 허용되지 않는 경우 귀하의 사례에 적용되는지 확인하십시오.
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}
Set
다른 모든 것을 얻지 않고 함수 만 다운로드 할 수 없다는 것은 부끄러운 일입니다 ...
function diff(a1, a2) {
return a1.concat(a2).filter(function(val, index, arr){
return arr.indexOf(val) === arr.lastIndexOf(val);
});
}
두 배열을 병합하면 고유 값이 한 번만 나타나므로 indexOf ()는 lastIndexOf ()와 같습니다.
한 배열에서 다른 배열을 빼려면 아래 스 니펫을 사용하십시오.
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;
});
두 번째 배열에는 존재하지 않는 첫 번째 배열의 항목 인 [ '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;
});
세트와 splat 연산자 (Firefox에서만 작동 할 때 호환성 표 확인 ) 가 포함 된 ES6이 도착 하면 다음과 같은 라이너 하나를 작성할 수 있습니다.
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" ]
입니다.
b.filter(x => !a.indexOf(x)))
O(n + m)
귀하의 솔루션이 O(n * m)
n과 m이 배열의 길이 인 곳입니다. 긴 목록을 가져 오면 솔루션이 몇 초 안에 실행되지만 몇 시간이 걸립니다.
a.filter(x => !b1.has(x))
더 간단합니다. 그리고 스펙은 복잡성이 평균적 n * f(m) + m
으로 f(m)
서브 리니어 일 때만 필요합니다 . 그것보다는 낫지 n * m
만 반드시 그런 것은 아닙니다 n + m
.
var difference = [...new Set([...a].filter(x => !b1.has(x)))];
왜 중복 'a'배열을 생성합니까? 왜 필터 결과를 세트로 변환 한 다음 다시 어레이로 변환합니까? 이 동일하지 않습니다var difference = a.filter(x => !b1.has(x));
difference
두 배열 사이를 계산하는 것이 Set
작업 중 하나입니다 . 이 용어 Set
는 조회 속도를 높이기 위해 기본 유형을 사용해야 함을 이미 나타냅니다 . 어쨌든 두 세트의 차이를 계산할 때 세 가지 순열이 있습니다.
[+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) );
이 예제는 함수형 프로그래밍의 의미에 대한 인상을 얻기위한 좋은 출발점이라고 생각합니다.
여러 가지 방법으로 서로 연결할 수있는 빌딩 블록을 사용한 프로그래밍.
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']
Joshaven Potter의 위의 답변은 훌륭합니다. 그러나 배열 B에는 없지만 배열 C에는없는 요소를 반환합니다. 예를 들어, 그렇다면 var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
==> 출력 [1,2,6]
하지만 출력 하지는 않습니다 [1,2,6,7]
.이 둘 사이의 실제 차이입니다. 위의 포터 코드를 계속 사용할 수 있지만 비교를 거꾸로 다시 실행하면됩니다.
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 ]
문제를 해결하는 또 다른 방법
function diffArray(arr1, arr2) {
return arr1.concat(arr2).filter(function (val) {
if (!(arr1.includes(val) && arr2.includes(val)))
return val;
});
}
diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]); // return [7, 4, 5]
또한 화살표 함수 구문을 사용할 수 있습니다.
const diffArray = (arr1, arr2) => arr1.concat(arr2)
.filter(val => !(arr1.includes(val) && arr2.includes(val)));
diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]); // return [7, 4, 5]
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]
difference
이 향후 버전에서 함수로 소개 되고이 함수에 다른 함수 서명이있는 경우이 함수를 사용하는 코드 또는 외부 라이브러리가 손상됩니다.
JavaScript의 필터 기능을 사용한 매우 간단한 솔루션 :
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
function diffArray(arr1, arr2) {
var newArr = [];
var myArr = arr1.concat(arr2);
newArr = myArr.filter(function(item){
return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0;
});
alert(newArr);
}
diffArray(a1, a2);
이건 어때요:
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))
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"]
filter
)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(', ')
);
length
값 을 캐시 할 이유가 없습니다 . 이미 평범한 재산입니다. jsperf.com/array-length-caching
이것은 작동합니다 : 기본적으로 두 배열을 병합하고 복제본을 찾고 복제되지 않은 것을 새로운 배열로 밀어 넣습니다.
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;
}
// es6 접근
function diff(a, b) {
var u = a.slice(); //dup the array
b.map(e => {
if (u.indexOf(e) > -1) delete u[u.indexOf(e)]
else u.push(e) //add non existing item to temp array
})
return u.filter((x) => {return (x != null)}) //flatten result
}
또 다른 대답하지만 보인다 그들은 여러 가지 알고리즘과 기술 지원을 비교 아무도 언급 jsperf : https://jsperf.com/array-difference-javascript 필터가 최상의 결과를 얻을 수 사용하는 것 같다. 감사
생각하기 ... 도전을 위해 ;-)이 작업을 수행 할 것입니다 ... (문자열, 숫자 등의 기본 배열의 경우) 중첩 배열이 없습니다.
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 ()를 호출하여 정렬하십시오.
나는 오래된 배열과 새로운 배열을 가져 와서 추가 된 항목의 배열과 제거 된 항목의 배열을주는 비슷한 기능을 원했고 효율적이기를 원했습니다.
제안 된 솔루션을 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};
}
다른 라이브러리를 사용하지 않는 간단한 답변을 찾고 있었고 여기에 언급되지 않은 내 자신을 생각해 냈습니다. 나는 그것이 얼마나 효율적인지 모르지만 작동합니다.
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;
}
내 코드의 경우 복제본도 필요하지만 항상 선호되는 것은 아닙니다.
주요 단점은 이미 거부 된 많은 옵션을 잠재적으로 비교하고 있다는 것입니다.
최상의 답변을위한 약간의 수정
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]]를 만들면 원래 값에서 값을 문자열로 변환하므로 실제 값을 잃었습니다.