이 두 배열이 있습니다. 하나는 ajax 요청의 정보로 채워지고 다른 하나는 사용자가 클릭하는 버튼을 저장합니다. 이 코드를 사용합니다 (샘플 번호로 채웠습니다).
var array1 = [2, 4];
var array2 = [4, 2]; //It cames from the user button clicks, so it might be disordered.
array1.sort(); //Sorts both Ajax and user info.
array2.sort();
if (array1==array2) {
doSomething();
}else{
doAnotherThing();
}
그러나 false
두 배열이 동일하지만 이름이 다른 경우에도 항상을 제공합니다 . (Chrome의 JS 콘솔에서 확인했습니다). 그래서,이 두 배열이 같은 것을 포함하는지 알 수있는 방법이 있습니까? 왜 주는가 false
? 첫 번째 배열의 어떤 값이 두 번째 배열에 없는지 어떻게 알 수 있습니까?
답변
function arraysEqual(_arr1, _arr2) {
if (!Array.isArray(_arr1) || ! Array.isArray(_arr2) || _arr1.length !== _arr2.length)
return false;
var arr1 = _arr1.concat().sort();
var arr2 = _arr2.concat().sort();
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i])
return false;
}
return true;
}
이것은 이전 답변과 달리 원래 배열을 수정하지 않습니다.
답변
배열 항목이 객체가 아닌 경우 (예 : 숫자 또는 문자열 인 경우) 결합 된 문자열을 비교하여 순서에 상관없이 동일한 멤버가 있는지 확인할 수 있습니다.
var array1= [10, 6, 19, 16, 14, 15, 2, 9, 5, 3, 4, 13, 8, 7, 1, 12, 18, 11, 20, 17];
var array2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17];
if(array1.sort().join(',')=== array2.sort().join(',')){
alert('same members');
}
else alert('not a match');
답변
두 배열이 동일한 값 (각 값의 발생 횟수 및 순서에 관계없이)을 갖는 경우에만 확인하려면 lodash 를 사용하여 수행 할 수 있습니다 .
_.isEmpty(_.xor(array1, array2))
짧고 간단하고 예쁘다!
답변
Array.prototype.compare = function(testArr) {
if (this.length != testArr.length) return false;
for (var i = 0; i < testArr.length; i++) {
if (this[i].compare) { //To test values in nested arrays
if (!this[i].compare(testArr[i])) return false;
}
else if (this[i] !== testArr[i]) return false;
}
return true;
}
var array1 = [2, 4];
var array2 = [4, 2];
if(array1.sort().compare(array2.sort())) {
doSomething();
} else {
doAnotherThing();
}
아마도?
답변
코드가 작동하지 않는 이유
JavaScript에는 원시 데이터 유형 과 비 원시 데이터 유형이 있습니다.
기본 데이터 타입의 경우 ==
와 ===
체크 바의 양쪽에있는 것들과 동일한 값을 가져야하는지 여부. 그것이 1 === 1
사실입니다.
배열 ==
과 같은 원시 데이터 유형이 아닌 ===
경우 참조 동등성을 확인하십시오. 즉 그들은 여부를 확인한다 arr1
와 arr2
같은 객체입니다. 귀하의 예에서 두 배열은 동일한 순서로 동일한 객체를 갖지만 동일하지는 않습니다.
솔루션
두 배열 arr1
및 arr2
은 다음과 같은 경우에만 동일한 멤버를 갖습니다.
- 모든 것이 들어
arr2
있습니다.arr1
과
- 모든 것이 들어
arr1
있습니다.arr2
그래서 이것은 트릭을 할 것입니다 (ES2016) :
const containsAll = (arr1, arr2) =>
arr2.every(arr2Item => arr1.includes(arr2Item))
const sameMembers = (arr1, arr2) =>
containsAll(arr1, arr2) && containsAll(arr2, arr1);
sameMembers(arr1, arr2); // `true`
Underscore를 사용하는이 두 번째 솔루션 은 수행하려는 작업에 더 가깝습니다.
arr1.sort();
arr2.sort();
_.isEqual(arr1, arr2); // `true`
isEqual
“깊은 평등”을 확인하기 때문에 작동 합니다. 즉, 참조 평등 이상을보고 값을 비교합니다.
세 번째 질문에 대한 해결책
또한에 arr1
포함되지 않은 항목을 찾는 방법을 물었 습니다 arr2
.
이렇게하면됩니다 (ES2015).
const arr1 = [1, 2, 3, 4];
const arr2 = [3, 2, 1];
arr1.filter(arr1Item => !arr2.includes(arr1Item)); // `[4]`
Underscore의 difference
: 메소드를 사용할 수도 있습니다 .
_.difference(arr1, arr2); // `[4]`
최신 정보
@Redu의 의견을 참조하십시오. 내 솔루션은에 대한 sameMembers
것이지만 염두에 두어야 할 것은으로 sameMembersInOrder
도 알려져 있습니다 deepEquals
.
업데이트 2
배열 멤버의 순서에 신경 쓰지 않는다면 ES2015 + Set
가 Array
. 위험한 원숭이 패치 를 구현 isSuperset
하고difference
사용 하는 방법에 대한 MDN 노트를 참조하십시오 .
답변
객체 동등성 검사 :JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())
위의 테스트는 http://www.w3schools.com/jsref/jsref_sort.asp에 설명 된대로 정렬 기능을 사용하는 경우 객체 배열에서도 작동합니다 .
플랫 JSON 스키마가있는 작은 배열에 충분할 수 있습니다.
답변
우리의 목표는 기본적으로 2 개의 배열이 동일한 집합인지 확인하는 것입니다. 집합 은 수학적으로 정의 된 집합 입니다. 가장 빠른 정렬은 점근 적으로 O (nlog (n)) 시간이 걸립니다. 따라서 배열을 정렬하면 최소한 O (nlog (n)) 시간이 걸립니다. 그러나이 작업을 더 빠르게 수행 할 수 있으며, 사전 데이터 구조에서 점근 적으로 O (n) 시간 (최악의 경우가 아닌 평균 사례 ) 이 걸립니다 . JS에서 사전은 단순히 키와 값이있는 객체입니다.
/** assumes array elements are primitive types
* check whether 2 arrays are equal sets.
* @param {} a1 is an array
* @param {} a2 is an array
*/
function areArraysEqualSets(a1, a2) {
const superSet = {};
for (const i of a1) {
const e = i + typeof i;
superSet[e] = 1;
}
for (const i of a2) {
const e = i + typeof i;
if (!superSet[e]) {
return false;
}
superSet[e] = 2;
}
for (let e in superSet) {
if (superSet[e] === 1) {
return false;
}
}
return true;
}
이 기능은 원시 형의 배열로 작동하고 가정합니다 a1
및 a2
배열입니다.