Сравнить два массива
Есть два массива, например:
mas1=[id1, id2, id3]; mas2=[id1, id3, id5]; Подскажите, как их сравнить, чтобы, не взирая на расположение элементов, находились похожие? |
Цитата:
2) у тя в них только строки будут? 3) строки могут быть одинаковые? 4) что в твоем понимании ПОХОЖИЕ? |
Что в результате то должно получиться? Какие значения?
|
Цитата:
|
1) размеры массивов могут отличаться - да
2) у тя в них только строки будут - да 3) строки могут быть одинаковые -да 4) что в твоем понимании ПОХОЖИЕ - id1=id1 |
Цитата:
|
вот наброска http://jsfiddle.net/bohdantheone/NQatM/
|
Цитата:
|
Цитата:
![]() |
Livaanderiamarum,
мои мысли - мои скакуны |
bohdantheone,
Вариант...
function duplicat(b, c) {
for (var d = [], e = {}, f = {}, a = 0; a < b.length; a++) e[b[a]] = !0;
for (a = 0; a < c.length; a++) f[c[a]] = !0;
for (var g in e) f[g] && d.push(g);
return d
};
alert(duplicat([1,7,2,8,5,12,45,67],[3,4,5,1,2]))
|
Цитата:
твоя функция даже не выдает результат РАВЕНСТВА или НЕ равенства) она выдает только общие найденные элементы) а это тут вообще не причем) но код обфуксировал зачетно))) |
/**
* сравнивает 2 массива не учитывая порядок элементов
*
* @param {Array}
* Первый массив
* @param {Array}
* Второй массив
* @return {Boolean}
*/
function test(arr, arr2){
if(arr.length != arr2.length) return false
var on = 0;
for( var i = 0; i < arr.length; i++ ){
for( var j = 0; j < arr2.length; j++ ){
if(arr[i] === arr2[j]){
on++
break
}
}
}
return on==arr.length?true:false
}
//сравниваем раз
var arr = [ 'привет', 'зима', "нарядная" ];
var arr2 = [ 'нарядная', 'зима', 'привет' ];
alert(test(arr, arr2))
//сравниваем два
var arr = [ 'СТОЛ', 'зима', "нарядная" ];
var arr2 = [ 'нарядная', 'зима', 'привет' ];
alert(test(arr, arr2))
|
Livaanderiamarum, а что она, по-твоему, делает? Если массив не пустой - совпадающие элементы есть)
|
Цитата:
А нужно сравнить массивы не взирая на порядок элементов) его функция определит равны они или нет ТОЛЬКО если не будет ни одного совпадения и выдастся пустой массив), если же будит хоть одно, то что-то да выдастся)) и придется еще потом сравнивать длины массива выданного и того который срванивали)) если длины равны то массивы равны) |
Цитата:
Цитата:
|
Цитата:
Нет, размеры массивов не могут отличаться он же потом написал, иначе как они будут РАВНЫМИ, а соответственно ни не будут ПОХОЖИ друг на друга, при том что "в задании" ему нужно найти похожие массивы) логика;) |
Livaanderiamarum,
Сравнение двух массивов не учитывая порядок елементов))) за два прохода
function duplicat(b, c) {
for (var d = [], e = {},a = 0; a < b.length; a++) e[b[a]]? e[b[a]]++:e[b[a]]=1 ;
for (a = 0; a < c.length; a++) e[c[a]] && d.push(c[a]) && e[c[a]]--;
return d.length == b.length && c.length == b.length
};
alert(duplicat([1,1,3,4,5],[5,4,3,1,1]))
alert(duplicat([1,1,3,4,5],[5,4,3,1,7]))
|
P.S. если два массива одинаковой длинны --- отсортировать оба и сравнить элементы по порядку ...:write:
|
рони,
вроде как все работает, спасибо |
Цитата:
|
А я бы использовал indexOf:
var a = [1,2,3];
var b = [1,4,3];
for (var i=0; i<b.length; i += 1){
if(a.indexOf(b[i]) != -1){
alert("Удаляем,"+b[i]);
}
}
indexOf реализация для массивов и строк можно взять тут А оптимизировать раньше времени, зло! Скрипт с легкостью можно переписать чтобы он оставлял нужные или собирал их в отдельный массив. |
Цитата:
|
в библиотеке underscore много функций для работы с массивами http://documentcloud.github.com/underscore/#arrays
может помогут? |
Цитата:
var a = [],b = [];
for (var i=0; i<1000; i++) {
a[i] = i;
b[i] = i;
}
var time = new Date();
function duplicat(b, c) {
for (var d = [], e = {},a = 0; a < b.length; a++) e[b[a]]? e[b[a]]++:e[b[a]]=1 ;
for (a = 0; a < c.length; a++) e[c[a]] && d.push(c[a]) && e[c[a]]--;
return d.length == b.length && c.length == b.length
};
rez_duplicat = duplicat(a,b);
time_duplicat = new Date((new Date()).getTime()-time.getTime()).getTime();
time = new Date();
function test(arr, arr2){
if(arr.length != arr2.length) return false
var on = 0;
for( var i = 0; i < arr.length; i++ ){
for( var j = 0; j < arr2.length; j++ ){
if(arr[i] === arr2[j]){
on++
break
}
}
}
return on==arr.length?true:false
}
rez_test = test(a,b);
time_test = new Date((new Date()).getTime()-time.getTime()).getTime();
alert("duplicat : " + rez_duplicat + " => time : " + time_duplicat + "\n"
+ "test : " + rez_test + " => time : " + time_test);
|
ну вот(( твоя быстрее.( а как она работает?
|
Цитата:
|
Livaanderiamarum,
при длине массивов 1000 ваша функция обращаеться к массивам 500 тысяч раз моя всего 2 тысячи в этом и выигрыш по времени |
Цитата:
|
Цитата:
но в методе пузырька даже меньше итераций, чем здесь :Р Цитата:
|
Livaanderiamarum,
Дока :
function duplicat(b, c) {
for (var d = [], e = {},a = 0; a < b.length; a++) e[b[a]]? e[b[a]]++:e[b[a]]=1 ;
// создаём обьект c, где ключами являются значения первого массива
// e[b[a]]? -> ключ есть ? это на тот случай если значения повторятся в массиве
// увеличиваем значение ключа на 1
// иначе если ещё ключа нет с таким значением
// создаём ключ со значением 1
for (a = 0; a < c.length; a++) e[c[a]] && d.push(c[a]) && e[c[a]]--;
//пробегаемся по второму массиву
// смотрим если значение элемента массива среди ключей
// нами созданного обьекта и его значение ещё не ноль -> e[c[a]]
// если ключ есть, заносим ключ в промежуточный массив d -> d.push(c[a])
// значение самого ключа уменьшаем
return d.length == b.length && c.length == b.length
// проверяем длину промежуточного массива d c длиной массива b
// они должны совпадать -> d.length == b.length
// плюс должна совпадать размерность исходных массивов -> c.length == b.length
// последнюю проверку можно поставить в начало
};
Ок? |
Livaanderiamarum,
Итого )))
function duplicat(b, c) {
if(b.length != c.length) return !1;
// должна совпадать размерность исходных массивов -> c.length == b.length
for (var d = 0, e = {},a = 0; a < b.length; a++) e[b[a]]? e[b[a]]++:e[b[a]]=1 ;
// создаём обьект e где ключами являются значения первого массива
// e[b[a]]? -> ключ есть ? это на тот случай если значения повторятся в массиве
// увеличиваем значение ключа на 1
// иначе если ещё ключа нет с таким значением
// создаём ключ со значением 1
for (a = 0; a < c.length; a++) e[c[a]] && d++ && e[c[a]]--;
// пробегаемся по второму массиву
// смотрим если значение элемента массива среди ключей
// нами созданного обьекта и его значение ещё не ноль -> e[c[a]]
// если ключ есть, увеличиваем счётчик d -> d++
// значение самого ключа уменьшаем
return d == b.length;
// проверяем счётчик d c длиной массива b
// они должны совпадать -> d == b.length
};
|
написано без учёта повторений одинаковых значений в массивах.
function compare(arr1, arr2){
if(arr1.length !== arr2.length) return false;
var i = 0, a = {};
// заносим в хеш значения первого массива.
while(i in arr1) {
// если на одинаковых позициях стоят одинаковые элементы, то зачем их проверять дальше?
if(arr1[i] !== arr2[i])
a[arr1[i]] = undefined;
i += 1;
}
// проходимся по элементам второго массива
// если значения нет в хеше (т.е. нет в первом массиве, то сразу возвращается false
while(i--) if(!(arr2[i] in a)) return false;
// массивы похожи
return true;
};
var a = ['a','b','c'], b = ['a','b','СТУЛ'], c = ['b','c','a'];
alert([compare(a,c), compare(b,c)]);
почему я использовал хеши и in ? на хабре увидел статью про то, что время на проверку существования через in во всех браузерах всегда равно нулю :) хотя вместо хеша можно было бы использовать массив первый и indexOf... но это не для IE. |
Ваши решения не учитывают маааленький нюанс - массивы могут быть и такими:
[ 1, '2', function b(){}, {c:d} ]
|
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
Напишите ка умельцы наши функцию быстрее чем моя для ПРОСТО СРАВНЕНИЯ двух массивов, при условии что в них лежат примитивные значения) и при условии что массивы раной длинны не равны. иными словами сравнить массивы игнорируя порядок элементов)
|
Цитата:
Цитата:
Вопрос ко всем - А где выполняется условие: Цитата:
|
Цитата:
ты вообще знаешь этот алгоритм? в чём он заключается и как работает? Цитата:
|
| Часовой пояс GMT +3, время: 04:28. |