Подтвердить что ты не робот

Есть ли идиоматический способ проверить равенство массива в Coffeescript?

Выражение

[1, 2, 3] == [1, 2, 3]

оценивает false в Coffeescript, но есть ли сжатый, идиоматический способ проверить равенство массива?

4b9b3361

Ответ 1

Если вы имеете дело с массивами чисел, и знаете, что в массивах нет значений null или undefined, вы можете сравнить их как строки:

a = [1, 2, 3]
b = [1, 2, 3]

console.log "#{a}" is "#{b}" # true
console.log '' + a is '' + b # true

Обратите внимание, однако, что это сломается, как только вы начнете сравнивать массивы других вещей, которые не являются цифрами:

a = [1, 2, 3]
b = ['1,2', 3]

console.log "#{a}" is "#{b}" # true

Если вы хотите более надежное решение, вы можете использовать Array#every:

arrayEqual = (a, b) ->
  a.length is b.length and a.every (elem, i) -> elem is b[i]

console.log arrayEqual [1, 2, 3], [1, 2, 3]   # true
console.log arrayEqual [1, 2, 3], [1, 2, '3'] # false
console.log arrayEqual [1, 2, 3], ['1,2', 3]  # false

Обратите внимание, что он сначала сравнивает длины массивов, так что arrayEqual [1], [1, 2, 3] не возвращает true.

Ответ 2

Если вы не возражаете представить Underscore.js зависимость, вы можете использовать некоторые из ее утилит. Это не очень элегантно, но я не могу придумать более простой способ сделать это с помощью обычного coffeescript:

a = [ 1, 2, 3 ]
b = [ 1, 2, 3 ]
equal = a.length == b.length and _.all( _.zip( a, b ), ([x,y]) -> x is y )

Ответ 3

Я бы не рассматривал эту идиоматику, но это было бы способом сделать это без добавления дополнительной библиотеки:

a = [1, 2, 3, 4]
b = [22, 3, 4]

areEqual = true
maxIndex = Math.max(a.length, b.length)-1
for i in [0..maxIndex]
    testEqual = a[i] is b[i]
    areEqual = areEqual and testEqual

console.log areEqual

Более чистый подход будет использовать функцию JavaScript reduce(). Это немного короче, но я не уверен, что поддержка браузеров уменьшена.

a = [1, 3, 4, 5]
b = [1, 3, 4, 5]

maxIndex = Math.max(a.length, b.length)-1
areEqual = true
[0..maxIndex].reduce (p, c, i, ar) -> areEqual = areEqual and (a[i] is b[i])

console.log "areEqual=#{areEqual}"

Ответ 4

Следующее работает отлично и не требует зависимостей:

arrayEqual = (ar1, ar2) ->
  JSON.stringify(ar1) is JSON.stringify(ar2)

Ответ 5

Я большой поклонник Sugar.js. Если вы используете это:

a = [1, 2, 3]
b = [1, 2, 3]
Object.equal(a, b)

Ответ 6

Эта функция возвращает true, если массивы имеют одинаковую длину, и все значения с одним индексом имеют одинаковое значение. Он выдает ошибку, если любой аргумент не является массивом.

isArray = Array.isArray || (subject) ->
    toString.call(subject) is '[object Array]'

compareArrays = (a, b) ->
    unless isArray(a) and isArray b
        throw new Error '`arraysAreEqual` called with non-array'

    return false if a.length isnt b.length

    for valueInA, index in a
        return false if b[index] isnt valueInA

    true