[javascript] lodash를 사용하여 배열 비교 (순서없이 항목 존재)

루프를 사용하여 할 수 있다는 것을 알고 있지만 우아한 방법을 찾으려고합니다.

두 개의 배열이 있습니다.

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];

lodash위의 두 배열이 동일한 지 확인하는 데 사용하고 싶습니다 . ‘동일’이란에 array1포함되지 않은 항목이 없음을 의미합니다 array2.

이러한 항목 간의 동등성을 확인하는 측면에서 :

['a', 'b'] == ['b', 'a'] 

또는

['a', 'b'] == ['a', 'b'] 

편지가 항상 순서대로 있기 때문에 둘 다 작동합니다.



답변

외부 배열을 정렬하면 _.isEqual()내부 배열이 이미 정렬되어 있으므로 사용할 수 있습니다 .

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
_.isEqual(array1.sort(), array2.sort()); //true

참고 .sort()배열을 변이 것입니다. 이것이 문제가되는 경우 먼저 (예 .slice()🙂 또는 스프레드 연산자 ( ...)를 사용하여 복사 하십시오 .

또는 Daniel Budick이 아래 댓글에서 권장하는대로 수행하십시오.

_.isEqual(_.sortBy(array1), _.sortBy(array2))

Lodash sortBy()는 배열을 변경하지 않습니다.


답변

이를 xor위해 lodashs 를 사용할 수 있습니다.

doArraysContainSameElements = _.xor(arr1, arr2).length === 0

배열 [1, 1]이 배열 [1]과 다르다고 생각하면 다음과 같이 성능을 약간 향상시킬 수 있습니다.

doArraysContainSameElements = arr1.length === arr2.length === 0 && _.xor(arr1, arr2).length === 0


답변

‘동일’이란 array2에 포함되지 않은 array1에 항목이 없음을 의미합니다.

항목이있는 경우 당신은 상관하지 않는 경우 잘 작동이에 대한 ()과 차이를 (), 평평하게 사용할 수 없습니다 에가 . 당신이 묻는 것처럼 들립니다 array1이 array2의 하위 집합 입니까?array2array1

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];

function isSubset(source, target) {
    return !_.difference(_.flatten(source), _.flatten(target)).length;
}

isSubset(array1, array2); // → true
array1.push('d');
isSubset(array1, array2); // → false
isSubset(array2, array1); // → true


답변

여기에 이미 답변이 있지만 여기에 순수한 JS 구현이 있습니다. 최적인지 확실하지 않지만 투명하고 읽기 쉽고 간단합니다.

// Does array a contain elements of array b?
const contains = (a, b) => new Set([...a, ...b]).size === a.length
const isEqualSet = (a, b) => contains(a, b) && contains(b, a)

의 이론적 근거는의 모든 요소를 ​​포함 contains()하는 경우 동일한 세트에 넣으면 크기가 변경되지 않는다는 것입니다.ab

예를 들어, if const a = [1,2,3,4]and const b = [1,2], then new Set([...a, ...b]) === {1,2,3,4}. 보시다시피 결과 집합에는 a.

여기에서 더 간결하게하기 위해 다음과 같이 요약 할 수 있습니다.

const isEqualSet = (a, b) => {
  const unionSize = new Set([...a, ...b])
  return unionSize === a.length && unionSize === b.length
}


답변

PURE JS (배열 및 하위 배열에 임의 순서의 요소가 2 개 이상있는 경우에도 작동합니다). 문자열이 포함되어있는 경우 ,로 사용 join('-')(UTF 될 수 있습니다) parametr 문자 문자열에 사용하지 않는

array1.map(x=>x.sort()).sort().join() === array2.map(x=>x.sort()).sort().join()


답변

_.difference함수를 사용 하여 차이가 있는지 확인할 수 있습니다 .

function isSame(arrayOne, arrayTwo) {
   var a = _.unique(arrayOne),
       b = _.unique(arrayTwo);

   if (a.length <= b.length) {
      a = arrayTwo;
      b = arrayOne;
      return _.isEmpty(_.difference(a.sort(), b.sort()));
   } else {
      return false;
   }

}

// examples
console.log(isSame([1, 2, 3], [1, 2, 3])); // true
console.log(isSame([1, 2, 4], [1, 2, 3])); // false
console.log(isSame([1, 2], [2, 3, 1])); // false
console.log(isSame([2, 3, 1], [1, 2])); // false

// Test cases pointed by Mariano Desanze, Thanks.
console.log(isSame([1, 2, 3], [1, 2, 2])); // false
console.log(isSame([1, 2, 2], [1, 2, 2])); // true
console.log(isSame([1, 2, 2], [1, 2, 3])); // false

도움이 되길 바랍니다.


답변

편집 :이 질문의 다차원 적 측면을 놓쳤으므로 사람들이 1 차원 배열을 비교하는 데 도움이 될 수 있도록 여기에 남겨 둡니다.

오래된 질문이지만 .sort()또는 사용 속도에 문제가 sortBy()있으므로 대신 이것을 사용했습니다.

function arraysContainSameStrings(array1: string[], array2: string[]): boolean {
  return (
    array1.length === array2.length &&
    array1.every((str) => array2.includes(str)) &&
    array2.every((str) => array1.includes(str))
  )
}

빨리 실패하도록 의도되었으며 내 목적에 따라 잘 작동합니다.