PDA

Просмотр полной версии : Как оставить в массиве только уникальные элементы


SvetozarPNZ
09.09.2011, 15:26
... чтобы из [0, 5, 4, 7, 4, 2 ,7, 5, 0] получить [0, 5, 4, 7, 2].

В Интернете встретил уже готовые функции в языках, например в PHP. Вроде в AS 3.0 такой функции нет. Написал свою.

function arrayOfUnique (mass:Array):Array {
mass.sort();
for (var i=mass.length; i!=0; i--) {
if (mass[i] == mass[i-1]) {
mass.splice(i,1);
i++;
}
}
return mass;
}

У меня тут через сортировку (в общем случае последовательность элементов значения не имеет) и возможно зря напрягаю процессор.

Есть ли более производительные и технически грамотные способы оставить в массиве только уникальные элементы?

Bgg
09.09.2011, 15:33
Можно без сортировки с использованием indexOf.

SvetozarPNZ
09.09.2011, 15:54
С использованием indexOf, мы для каждого элемента должны прогнать весь массив? Не уменьшаем ли производительность...

maxkar
09.09.2011, 16:11
Можно в множество (поля динамического объекта) сложить, а затем из полей составить новый массив.
Что-то вроде

const obj : Object = {};
for each (var i : int in arr) {
obj[i] = 1;
}
const res : Array = new Array();
for (var s : String in obj) {
res.push(int(s));
}

Производительность нужно замерять. Может зависеть от характеристик исходного массива.

Genzo
09.09.2011, 16:17
var arrayUnique:Array = array.filter(function(item:* , index:int, array:Array) {
if(array.indexOf(item , index + 1) != -1) return false;
else return true;}
);

Добавлено через 7 минут
По умолчанию Array. sort() действует следующим образом:

Сортировка зависит от регистра (Z предшествует a).
Сортировка выполняется в восходящем порядке (a предшествует b).
Массив изменяется, отражая порядок сортировки; несколько элементов, имеющих идентичные поля сортировки последовательно размещаются в отсортированном массиве без определенного порядка.
Все элементы независимо от типа данных сортируются так, как если бы это были строки. Число 100 предшествует числу 99, поскольку «1» — это строковое значение, которое меньше «9».

А если у вас в массиве объекты? т.ч. indexOf

mayakwd
09.09.2011, 17:22
http://www.kirupa.com/forum/showthread.php?223798-ActionScript-3-Tip-of-the-Day/page44

SvetozarPNZ
12.09.2011, 15:18
Хороший скрипт! Моя сортировка вырубалась при 70 тыс. элементах. А этот работает с 20 млн. Не пойму, что означает строчка в условии?

function arrayUniqueObj(s:Array):Array
{
var n:int = s.length;
var uniq:Array = new Array();
var obj:Object = new Object();
for(var i:int = 0; i < n; i++) if(!obj[s[i]]) { obj[s[i]] = true; uniq.push(s[i]); }
return uniq;
}

Добавлено через 21 минуту
Разобрался сам. Объект может использоваться как ассоциативный массив.

mayakwd
12.09.2011, 15:49
indexOf сам по себе медленный. использование Object или Dictionary в качестве хэша дает существенный прирост при сортировке.

а условие означает следующее:
если элемент под индексом i из массива s отсутствует в хэше, то заносим его в уникальный массив и добавляем в хэш.