Underscore.js - Определяет, соответствуют ли все значения в массиве массивов

У меня есть массив массивов, который выглядит примерно так:

[["Some string", "Some other string"],["Some third string", "some fourth string"]]

Я думаю, что я могу использовать метод _.all в Underscore, чтобы определить, соответствуют ли все массивы 100% (это все их значений совпадают), но я не уверен, как записать требуемый итератор для запуска проверки.

У кого-нибудь есть идея?

Ответы

Ответ 1

Попробуйте этот парень (не зависит от заказа):

function allArraysAlike(arrays) {
  return _.all(arrays, function(array) {
    return array.length == arrays[0].length && _.difference(array, arrays[0]).length == 0;
  });
}

Предполагается, что вы хотите, чтобы все массивы содержали все те же элементы в том же порядке, что и один другой (поэтому для ввода вашего примера функция должна возвращать false).

Ответ 2

Почему не пересечение? (если вы действительно хотите использовать для этого некоторые функции Underscore) http://underscorejs.org/#intersection

Если массивы имеют одинаковую длину, а длина пересечения равна длине массивов, то все они содержат одинаковые значения.

Ответ 3

Мои предпочтения:

_.isEqual(_.sortBy(first), _.sortBy(second))

И если порядок имеет значение:

_(first).isEqual(second)

Ответ 4

Используйте знак подчеркивания, чтобы определить разницу между ними, и проверьте длину массива. Легкий способ сделать это:

_.isEmpty(_.difference(array1, array2)) && _.isEmpty(_.difference(array2, array1))

Это вернет true, если они будут одинаковыми и false, если они не являются.

Ответ 5

_.isEmpty(_.xor(array1, array2))

Ответ 6

Если вы хотите проверить, что элементы одинаковые и в том же порядке, я бы пошел с:

arrayEq = function(a, b) {
  return _.all(_.zip(a, b), function(x) {
    return x[0] === x[1];
  });
};

Еще более аккуратно в coffeescript:

arrayEq = (a,b) ->
    _.all _.zip(a,b), (x) -> x[0]==x[1]

Ответ 7

Моя реализация с http://underscorejs.org/

/**
 * Returns true if the arrays are equal
 *
 * @param {Array} array1
 * @param {Array} array2
 * @returns {boolean}
 */
equal: function ( array1, array2 )
{
    return ( array1.length === array2.length)
        && (array1.length === _.intersection( array1, array2 ).length);
}

Ответ 8

Если вам не нужно знать, какие элементы неравны, используйте транзитивность:

function allEqual(list) {
  return _.all(list.slice(1), _.partial(_.isEqual, list[0]));
}
allEqual([2, 2, 2, 2]) //=> true
allEqual([2, 2, 3, 2]) //=> false
allEqual([false])      //=> true
allEqual([])           //=> true

Ответ 9

Я не могу прокомментировать ответ Дэна Тао, небольшое изменение, чтобы пропустить проверку первого массива против себя (ненужный вызов _.difference)

function allArraysAlike(arrays) {
    return _.all(arrays, function(array) {
        if(array === arrays[0]) return true;
        return array.length == arrays[0].length && _.difference(array, arrays[0]).length == 0;
    });
}