source

배열이 무시 순서와 동일해야 합니다.

factcode 2023. 10. 11. 21:01
반응형

배열이 무시 순서와 동일해야 합니다.

Jasmine을 사용하면 2개의 배열에 동일한 요소가 포함되어 있지만 반드시 동일한 순서일 필요는 없는지 테스트할 수 있는 방법이 있습니까?

array1 = [1,2,3];
array2 = [3,2,1];

expect(array1).toEqualIgnoreOrder(array2);//should be true

편집

에 2.8 arrayWithExactContents실제 값이 샘플의 모든 요소를 순서대로 포함하는 배열일 경우 이 값은 성공합니다.

케크스마스타의 답변 보기


원래(오래된) 답변

정수 또는 다른 원시 값일 경우 비교하기 전에 먼저 사용할 수 있습니다.

expect(array1.sort()).toEqual(array2.sort());

개체가 있는 경우 함수와 결합하여 비교할 식별자를 추출합니다.

array1 = [{id:1}, {id:2}, {id:3}];
array2 = [{id:3}, {id:2}, {id:1}];

expect(array1.map(a => a.id).sort()).toEqual(array2.map(a => a.id).sort());

표준 jest에서 expect.arrayContaining(array)를 사용할 수 있습니다.

  const expected = ['Alice', 'Bob'];
  it('matches even if received contains additional elements', () => {
    expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
  });

jasmine 버전 2.8 이상은

jasmine.arrayWithExactContents()

배열에 나열된 요소가 순서에 상관없이 정확하게 포함될 것으로 예상됩니다.

array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayWithExactContents(array2))

https://jasmine.github.io/api/3.4/jasmine.html 참조

농담으로 확장된 패키지는 테스트를 단순화할 수 있는 주장을 거의 제공하지 않으며, 상세하지 않으며 테스트에 실패한 경우 오류가 더욱 명확합니다.

이 경우 SameMembers를 포함하는 데 사용할 수 있습니다.

expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);

단순한...

array1 = [1,2,3];
array2 = [3,2,1];

expect(array1).toEqual(jasmine.arrayContaining(array2));
// check if every element of array2 is element of array1
// to ensure [1, 1] !== [1, 2]
array2.forEach(x => expect(array1).toContain(x))

// check if every element of array1 is element of array2
// to ensure [1, 2] !== [1, 1]
array1.forEach(x => expect(array2).toContain(x))

// check if they have equal length to ensure [1] !== [1, 1]
expect(array1.length).toBe(array2.length)
//Compare arrays without order
//Example
//a1 = [1, 2, 3, 4, 5]
//a2 = [3, 2, 1, 5, 4]
//isEqual(a1, a2) -> true
//a1 = [1, 2, 3, 4, 5];
//a2 = [3, 2, 1, 5, 4, 6];
//isEqual(a1, a2) -> false


function isInArray(a, e) {
  for ( var i = a.length; i--; ) {
    if ( a[i] === e ) return true;
  }
  return false;
}

function isEqArrays(a1, a2) {
  if ( a1.length !== a2.length ) {
    return false;
  }
  for ( var i = a1.length; i--; ) {
    if ( !isInArray( a2, a1[i] ) ) {
      return false;
    }
  }
  return true;
}

각 요소를 한 개체 Each 는() 에합니다)에status기).

const expected = [ 
     { count: 1, status: "A" },
     { count: 3, status: "B" },
];
result.forEach((item) => {
     expect(expected.find(a => a.status === item.status)).toEqual(item);
})

여기서 사용할 수 있도록 무시 순서를 설정합니다.

expect(new Set(a)).toEqual(new Set(b))
function equal(arr1, arr2){
    return arr1.length === arr2.length
    &&
    arr1.every((item)=>{
        return arr2.indexOf(item) >-1
    }) 
    &&
    arr2.every((item)=>{
        return arr1.indexOf(item) >-1
    })
}

여기서는 먼저 두 배열의 길이가 동일한지 확인한 다음 모든 요소가 다른 배열에 있는지 확인합니다.

다음은 어떤 숫자나 배열에도 적합한 솔루션입니다.

https://gist.github.com/tvler/cc5b2a3f01543e1658b25ca567c078e4

const areUnsortedArraysEqual = (...arrs) =>
  arrs.every((arr, i, [first]) => !i || arr.length === first.length) &&
  arrs
    .map(arr =>
      arr.reduce(
        (map, item) => map.set(item, (map.get(item) || 0) + 1),
        new Map(),
      ),
    )
    .every(
      (map, i, [first]) =>
        !i ||
        [...first, ...map].every(([item]) => first.get(item) === map.get(item)),
    );

일부 테스트(이 질문에 대한 몇 가지 답변은 동일한 값의 항목이 여러 개인 어레이를 설명하지 않으므로 [1, 2, 2] 및 [1, 2]가 참으로 잘못 반환됨)

[1, 2] true
[1, 2], [1, 2] true
[1, 2], [1, 2], [1, 2] true
[1, 2], [2, 1] true
[1, 1, 2], [1, 2, 1] true
[1, 2], [1, 2, 3] false
[1, 2, 3, 4], [1, 2, 3], [1, 2] false
[1, 2, 2], [1, 2] false
[1, 1, 2], [1, 2, 2] false
[1, 2, 3], [1, 2], [1, 2, 3] false

이 알고리즘은 각 항목이 고유한 배열에 적합합니다.그렇지 않은 경우 중복 여부를 확인할 항목을 추가할 수 있습니다.

tests = [
  [ [1,0,1] , [0,1,1] ],
  [ [1,0,1] , [0,0,1] ], //breaks on this one...
  [ [2,3,3] , [2,2,3] ], //breaks on this one also...
  [ [1,2,3] , [2,1,3] ],
  [ [2,3,1] , [1,2,2] ],
  [ [2,2,1] , [1,3,2] ]
]

tests.forEach(function(test) {
  console.log('eqArraySets( '+test[0]+' , '+test[1]+' ) = '+eqArraySets( test[0] , test[1] ));
});


function eqArraySets(a, b) {
	if ( a.length !== b.length ) { return false; }
	for ( var i = a.length; i--; ) {
		if ( !(b.indexOf(a[i])>-1) ) { return false; }
		if ( !(a.indexOf(b[i])>-1) ) { return false; }
	}
	return true;
}

이 접근 방식은 이론적으로 최악의 경우 런타임 성능이 더 떨어지지만 어레이에서 쓰기를 수행하지 않기 때문에 많은 환경에서 더 빠를 수 있습니다(성능 테스트는 아직 완료되지 않았습니다).

경고: Torben이 언급한 바와 같이, 이 접근 방식은 두 어레이 모두에 고유한(반복되지 않는) 요소가 있는 경우에만 적용됩니다(여기에 있는 다른 답변들과 마찬가지로).

/**
 * Determine whether two arrays contain exactly the same elements, independent of order.
 * @see https://stackoverflow.com/questions/32103252/expect-arrays-to-be-equal-ignoring-order/48973444#48973444
 */
function cmpIgnoreOrder(a, b) {
  const { every, includes } = _;
  return a.length === b.length && every(a, v => includes(b, v));
}

// the following should be all true!
const results = [
  !!cmpIgnoreOrder([1,2,3], [3,1,2]),
  !!cmpIgnoreOrder([4,1,2,3], [3,4,1,2]),
  !!cmpIgnoreOrder([], []),
  !cmpIgnoreOrder([1,2,3], [3,4,1,2]),
  !cmpIgnoreOrder([1], []),
  !cmpIgnoreOrder([1, 3, 4], [3,4,5])
];

console.log('Results: ', results)
console.assert(_.reduce(results, (a, b) => a && b, true), 'Test did not pass!');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>

현재 이 USE CASE에 대한 일치자가 있습니다.

https://github.com/jest-community/jest-extended/pull/122/files

test('passes when arrays match in a different order', () => {
  expect([1, 2, 3]).toMatchArray([3, 1, 2]);
  expect([{ foo: 'bar' }, { baz: 'qux' }]).toMatchArray([{ baz: 'qux' }, { foo: 'bar' }]);
});

저는 현재 (TypeScript용) 도우미 기능을 사용하고 있습니다.고유한 요소가 아닌 어레이도 지원됩니다.

function expectArraysToBeEqualIgnoringOrder<T>(arr1: T[], arr2: T[]) {

    while(arr1.length > 0) {

        expect(arr1.length).toEqual(arr2.length)

        const elementToDelete = arr1[0]

        arr1 = arr1.filter(element => element !== elementToDelete)
        arr2 = arr2.filter(element => element !== elementToDelete)

    }

    expect(arr2.length).toEqual(0)

}

대부분의 다른 답변들은 다음과 같은 경우를 올바르게 처리하지 못합니다.

array1: [a, b, b, c]
array2: [a, b, c, c]

여기서는 두 어레이의 요소 수가 같고 두 어레이 모두 다른 어레이의 모든 요소를 포함하지만 서로 다른 어레이이므로 테스트에 실패해야 합니다.O(n^2)(정확히는 (n^2 + n) / 2)에서 실행되므로 매우 큰 배열에는 적합하지 않지만 쉽게 정렬되지 않는 배열에는 적합하므로 O(n * log(n))에서 비교할 수 없습니다.

언급URL : https://stackoverflow.com/questions/32103252/expect-arrays-to-be-equal-ignoring-order

반응형