Написание правильного теста утверждений для равных массивов - PullRequest
0 голосов
/ 22 сентября 2018

У меня проблемы с написанием правильного теста утверждения.Он отлично работает на отдельных массивах, но не работает при тестировании массива массивов.Кажется, проблема в areEqualItems, но я не знаю почему.Что я делаю не так?

function assertArraysEqual(actual, expected, testName){
    var areEqualLength = actual.length === expected.length;
    var areEqualItems = actual.every(function(item, i){
        return item === expected[i]
    });
    if(areEqualLength && areEqualItems){
        console.log('passed');
    } else {
        console.log('FALIED [' + testName + '] Expected ' + expected + ', but got ' + actual);
    }
}

var arr1 = [0,1,2,3];
var arr2 = [0,1,2,3];

var arr3 = [ [0,1,2,3], [0,1,2,3] ];
var arr4 = [ [0,1,2,3], [0,1,2,3] ];

assertArraysEqual(arr1, arr2, 'arrays should be equal'); // passed
assertArraysEqual(arr3, arr4, 'arrays should be equal'); // FALIED [arrays should be equal] Expected 0,1,2,3,0,1,2,3, but got 0,1,2,3,0,1,2,3

Ответы [ 6 ]

0 голосов
/ 22 сентября 2018

Сравнение массивов (и их дочерних массивов, и их дочерних массивов) может стать очень дорогим довольно быстро.Кроме того, в написанном вами коде и принятом ответе не учитываются ассоциативные массивы (или объекты).Я бы предложил преобразовать оба массива в строки JSON, а затем сравнить их как строки.

function assertArraysEqual(actual, expected, testName){
    if ( actual.length === expected.length && JSON.stringify(actual) == JSON.stringify(expected) ) console.log('passed');
    else console.log('FALIED [' + testName + '] Expected ' + expected + ', but got ' + actual);
}

var arr1 = [0,1,2,3];
var arr2 = [0,1,2,3];

var arr3 = [ [0,1,2,3], [0,1,2,3] ];
var arr4 = [ [0,1,2,3], [0,1,2,3] ];

assertArraysEqual(arr1, arr2, 'arrays should be equal'); 
assertArraysEqual(arr3, arr4, 'arrays should be equal');
0 голосов
/ 22 сентября 2018

Почему бы вам не упорядочить массивы, а затем сравнить?Это значительно сократит ваш код.

function assertArraysEqual(actual, expected) {
    const actualStr = JSON.stringify(actual);
    const expectedStr = JSON.stringify(expected);
    return actualStr === expectedStr;
}
0 голосов
/ 22 сентября 2018

Вы можете сделать очень краткую функцию равенства.Просто проверьте граничные случаи, когда длины не равны или они не являются массивами, а затем выполните рекурсивный анализ:

var arr3 = [[0,1,2,3], [0,1,2,3]];
var arr4 = [[0,1,2,3], [0,1,2,3]];


function equal(a, b){
  if (!Array.isArray(a) || !Array.isArray(b)) return a === b
  if (a.length !== b.length) return false

  return a.every((item, i) => equal(item, b[i]))
}

console.log(equal(arr3, arr4))
console.log(equal([[1, 2], [3, 4]], [[2, 2], [3, 4]]))
0 голосов
/ 22 сентября 2018

Другое решение - передать эту работу третьей стороне, например, lodash.

В Lodash есть метод isEqual, который может выполнить эту работу за вас.

Ознакомьтесь с документацией здесь .

Код образца:

function assertArraysEqual(actual, expected, testName) {
    if (_.isEqual(actual, expected)) {
        console.log('passed');
    } else {
        console.log(`FALIED [${testName}] Expected ${expected}, but got ${actual}`);
    }
}
0 голосов
/ 22 сентября 2018

Вы должны сделать его рекурсивным, если элемент является другим массивом.

Также нет смысла проверять, равны ли элементы, когда длины не совпадают.

Это будетТакже будет лучше, если вы отключите функцию сравнения.Мне пришлось сделать это условным от того, был ли указан аргумент testName, чтобы он не регистрировался во время всех рекурсивных вызовов.

function assertArraysEqual(actual, expected, testName) {
  var areEqualLength = actual.length === expected.length;
  var areEqualItems = areEqualLength && actual.every(function(item, i) {

    if (Array.isArray(item) && Array.isArray(expected[i])) {
      return assertArraysEqual(item, expected[i]);
    } else {
      return item === expected[i]
    }
  });
  if (testName) {
    if (areEqualItems) {
      console.log('passed');
    } else {
      console.log('FAILED [' + testName + '] Expected ' + expected + ', but got ' + actual);
    }
  }
  return areEqualItems;
}

var arr1 = [0, 1, 2, 3];
var arr2 = [0, 1, 2, 3];

var arr3 = [
  [0, 1, 2, 3],
  [0, 1, 2, 3]
];
var arr4 = [
  [0, 1, 2, 3],
  [0, 1, 2, 3]
];
var arr5 = [
  [0, 1, 2, 3],
  [0, 2, 3, 4]
];

assertArraysEqual(arr1, arr2, 'arrays should be equal'); // passed
assertArraysEqual(arr3, arr4, 'arrays should be equal'); // FALIED [arrays should be equal] Expected 0,1,2,3,0,1,2,3, but got 0,1,2,3,0,1,2,3
assertArraysEqual(arr3, arr5, 'arrays should not be equal');
0 голосов
/ 22 сентября 2018

Вот небольшая справка о том, как сделать его рекурсивным:

function areArraySame(one, two) {
    var length = one.length === two.length;
    var allElems = one.every(function(item, i) {
        if (item instanceof Array) {
            return areArraySame(item, two[i]); // <-- recurse!
        }
        return item === two[i];
    });

    return length && allElems;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...