2014-02-04 3 views
2

Есть ли способ проверить, являются ли два JavaScript ArrayBuffers равными? Я хотел бы написать тест для метода компоновки сообщений. Единственный способ, которым я нашел, - преобразовать ArrayBuffer в строку, а затем сравнить. Я что-то пропустил?Как проверить, являются ли два массива в Javascript равными?

После кода дает ложное, даже если я думаю, что это должно быть правдой:

(function() { 
    'use strict'; 

    /* Fill buffer with data of Verse header and user_auth 
    * command */ 
    var buf_pos = 0; 
    var name_len = 6 
    var message_len = 4 + 1 + 1 + 1 + name_len + 1; 

    var buf = new ArrayBuffer(message_len); 
    var view = new DataView(buf); 
    /* Verse header starts with version */ 
    view.setUint8(buf_pos, 1 << 4); /* First 4 bits are reserved for version of protocol */ 
    buf_pos += 2; 
    /* The lenght of the message */ 
    view.setUint16(buf_pos, message_len); 
    buf_pos += 2; 

    buf_pos = 0; 
    var buf2 = new ArrayBuffer(message_len); 
    var view2 = new DataView(buf); 
    /* Verse header starts with version */ 
    view2.setUint8(buf_pos, 1 << 4); /* First 4 bits are reserved for version of protocol */ 
    buf_pos += 2; 
    /* The lenght of the message */ 
    view2.setUint16(buf_pos, message_len); 
    buf_pos += 2; 


    if(buf == buf2){ 
     console.log('true'); 
    } 
    else{ 
     console.log('false'); 
    } 


}()); 

Если я пытаюсь сравнить вид и VIEW2 это ложь снова.

ответ

3

Вы не можете сравнивать два объекта непосредственно в JavaScript с использованием == или ===.
Эти операторы будут проверять только равенство ссылок (т. Е. Если выражения ссылаются на один и тот же объект).

Вы можете, однако, использовать DataView или ArrayView объекты для извлечения значений конкретных частей объектов ArrayBuffer и их проверки.

Если вы хотите, чтобы проверить заголовки:

if ( view1.getUint8 (0) == view2.getUint8 (0) 
    && view1.getUint16(2) == view2.getUint16(2)) ... 

Или, если вы хотите, чтобы проверить глобальности ваших буферов:

function equal (buf1, buf2) 
{ 
    if (buf1.byteLength != buf2.byteLength) return false; 
    var dv1 = new Int8Array(buf1); 
    var dv2 = new Int8Array(buf2); 
    for (var i = 0 ; i != buf1.byteLength ; i++) 
    { 
     if (dv1[i] != dv2[i]) return false; 
    } 
    return true; 
} 

Если вы хотите реализовать сложную структуру данных на основе ArrayBuffer, Я предлагаю создать свой собственный класс, иначе вам придется прибегать к громоздким необработанным экземплярам DataView/ArrayView каждый раз, когда вы захотите переместить спичку внутри и снаружи структуры.

+0

Спасибо. Это именно то, что мне нужно сделать - реализовать набор классов для обработки сообщений через websocket. Я хотел бы, чтобы методы и конечный автомат были покрыты испытаниями. – JirkaV

+0

Угадайте ... это сработает, если мы преобразуем оба массива в String (скажем, базу 64), а затем сравним их – Amarsh

+0

Это может быть, но я сомневаюсь, что это было бы более эффективно. –

0

Вы всегда можете преобразовать массивы в строки и сравнить их. Например.

let a = new Uint8Array([1, 2, 3, 4]); 
let b = new Uint8Array([1, 2, 3, 4]); 
if (a.toString() == b.toString()) { 
    console.log("Yes"); 
} else { 
    console.log("No"); 
} 
+1

Это может не работать, если один из буферов дополняется 0 с каждой стороны. Если вы 'toString' Buffer с добавленными 0, длина возвращаемой строки не будет отражать фактическую длину строк, то сравнение строк не будет работать. например 'Buffer.from ([80]). ToString()' is "P". 'Buffer.from ([80, 0]). ToString()' также является «P», но длина второго равна 2. Даже если строка явно имеет только одну букву. Обрезка строки также не работает. –

Смежные вопросы