Javascript: сравните три массива - PullRequest
4 голосов
/ 08 октября 2011

Я хочу сравнить множество массивов и объединить любые идентичные:

A = [1,2,3];
B = [1,2,3];
C = [1,2,3];

D = [10,11,12];
E = [10,11,12];
F = [10,11,12];

G = [13,14];
H = [13,14];

Если есть идентичные массивы, я бы хотел создать новые массивы из идентичных:

I = [1,2,3];
J = [10,11,12];
K = [13,14];

Нужно ли мне проходить через каждый элемент в одном массиве против ВСЕХ элементов в других массивах?

for (var i in A) {
    for (var j in B) {
        if (A[i] == J[j]) {
            // create new arrays
        }
    }
}

и т.д ...

Тогда, создавать новые массивы из совпадений? Похоже, много накладных расходов.

Какой лучший способ сделать это?

Спасибо!

Ответы [ 6 ]

5 голосов
/ 08 октября 2011

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

var myArrays = [A,B,C,D,E,F,G],
    uniques = [],
    hashes = {};

for (var i=0; i < myArrays.length; i++) {
    var hash = JSON.stringify(myArrays[i]); // or .toString(), or whatever
    if (!(hash in hashes)) {
        hashes[hash] = true;
        uniques.push(myArrays[i]);
    }
}
// uniques now holds all unique arrays
1 голос
/ 08 октября 2011

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

(см. Скрипку здесь )

Код:

A = [1,2,3];
B = [1,2,3];
C = [1,2,3];

D = [10,11,12];
E = [10,11,12];
F = [10,11,12];

G = [13,14];
H = [13,14];

function compareArr(arrList){
    var S = '@' + arrList.join('@');
    var re = /(@[^@]+)(@.*)?(\1)(@|$)/gi
    var afterReplace=''; var i=0;
    while(afterReplace!=S && i<100){
        afterReplace=S;
        S = S.replace( re, "$1$2$4" )
        i++
    }

    return S.substr(1,S.length-1).replace(/@/g,'<br>')
}

$('html').append( compareArr([A,B,C,D,E,F,G,H]) )

Стратегия заключается в объединении всего массива в строку с "@" в качестве разделителя. Затем с помощью регулярных выражений замените весь дублированный фрагмент внутри строки, наконец разбейте строку и получите список уникальных массивов.

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

1 голос
/ 08 октября 2011

Если вы просто сравниваете массивы примитивов, чисел или строк, скажем, вы можете сравнить их строковое представление.

function simpleArrayMatch(A,B){
    return String{A)===String(B);
}
1 голос
/ 08 октября 2011

Ну ... я бы так сделал

function combine(arr1, arr2)
{
    if(arr1.join(',') === arr2.join(','))
        return arr1;
}

или для многих массивов

function combine(arrList)
{
    var pass = true;
    var compareArray = arrList[0];
    for(var i in arrList)
        pass = pass && (arrList[i].join(',') === compareArray.join(','));
    if(pass)
        return compareArray;
}

arr = combine([[1,2,3],[1,2,3],[1,2,3]]); // results in [1,2,3]
1 голос
/ 08 октября 2011

В зависимости от вашего определения идентификатора, вы можете просто преобразовать в строку и сравнить их.

if (A.toString() == B.toString()) { //combine }
0 голосов
/ 08 октября 2011

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

function compareArrays(arr1,arr2)
{
    if (arr1.length != arr2.length) return false;
    for (var i = 0; i < arr2.length; i++) 
    {
        if (arr1[i].compareArrays) 
        { //likely nested arr2ay
            if (!arr1[i].compareArrays(arr2[i])) return false;
            else continue;
        }
        if (arr1[i] != arr2[i]) return false;
    }
    return true;
}

Тогда вам просто нужно использовать эту функцию при циклическом просмотре массивов.

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