|
|
|
| Форумчане, доброго времени суток :)
Есть проблемка, помогите решить её.
Имееем код:
var project;
var projects = [];
var uniqueProjects = [];
function f1() {
for(var i = 1; i < length1; i++) {
...
for(var j = 0; j < length2; j++) {
...
projects.push(project);
}
}
uniqueProjects = arrayUnique(projects);
for(k = 0; k < uniqueProjects.length; k++) {
...uniqueProjects[k]...
//здесь, скажем так, 'главный код' :) В циклах выше, я создавал массив projects со всеми элементами project, потом выбирал уникальные значения - uniqueProjects = arrayUnique(projects);. После моих изменений всё работает в 3-4 раза медленнее.. Это не есть гут!
}
}
function arrayUnique(ar) {
var a = [];
var l = ar.length;
for(var i = 0; i < l; i++) {
for(var j = i + 1; j < l; j++) {
if(ar[i] === ar[j])
j = ++i;
}
a.push(ar[i]);
}
return a;
}
|
Как ускорить поиск уникальных значений в данном случае? По-моему метод push() и arrayUnique() работает медленно... Какие мысли у кого? | |
|
|
|
|
|
|
|
для: HelloMoto
(04.12.2009 в 22:45)
| | Много быстрее:
function arrayUnique (ar)
{
for (var s = [], r = [], j = k = 0, x = ar.length; j < x; j++)
if (!s [ar [j]]) {s [ar [j]] = 69; r [k++] = ar [j]} return r;
}
| и безо всяких "пушей". | |
|
|
|
|
|
|
|
для: АЯ
(05.12.2009 в 07:30)
| | - что это значит? | |
|
|
|
|
|
|
|
для: HelloMoto
(05.12.2009 в 14:00)
| | Это значит то же самое, что и:
s [ar [j]] = 3.1415926;
или
s [ar [j]] = true;
или
s [ar [j]] = 'Abrakadabra';
| и вообще всё что угодно, КРОМЕ:
нуля, undefined, null, пустой строки или false. | |
|
|
|
|
|
|
|
для: АЯ
(05.12.2009 в 23:02)
| | А подскажите плз ещё вот что - как в вашей функции возвращать true если в r добавлен новый уникальный элемент и false в любом другом? | |
|
|
|
|
|
|
|
для: HelloMoto
(07.12.2009 в 17:29)
| | Извините, последний ваш вопрос я не понял.
Как мне видится, вы передаёте функции один массив,
в котором могут быть повторяющиеся элементы:
massiv_1 = ['Иванов', 'Петров', 'Иванов', 'Сидоров', 'Кузнецов', 'Иванов'];
|
Задача функции - вычеркнуть "второго" и "третьего" Иванова,
оставив первого:
['Иванов', 'Петров', 'Иванов', 'Сидоров', 'Кузнецов', 'Иванов'];
| т.е. вернуть на выходе другой массив, в котором нет "однофамильцев"
и есть только один Иванов (уникальный):
massiv_2 = ['Иванов', 'Петров', 'Сидоров', 'Кузнецов'];
|
Моя функция с этим справляется. "Быстро и дешево".
Что вам надо?
Вы хотите добавить какую-то ещё "функциональность" для этой функции?
Или же просто хотите понять механизм работы этой функции?
Объясните подробнее. | |
|
|
|
|
|
|
|
для: АЯ
(07.12.2009 в 18:03)
| | Походу задача немного меняется.
Надо вот что:
- есть массив ar, содержащий абсолютно любые элементы.
В функции arrayUnique(), проходя по массиву ar, в случае если текущего значения нет в массиве ar, то есть оно уникальное, вернуть true, иначе вернуть false. То есть arrayUnique должна возвращать true или false.
То есть:
....
if(arrayUnique(ar, a)){ // вызов
....
function arrayUnique(ar, a) {
ar.push(a);
вот здесь нужно делать то, что я написал выше
}
|
| |
|
|
|
|
|
|
|
для: HelloMoto
(07.12.2009 в 18:22)
| | Как-то вы невнятно объясняетесь. Или у меня с "понималкой" плохо сегодня :-)
Сейчас я понял только то, что вам нужна иная функция.
И понял, что в функцию вы теперь передаёте два аргумента: массив и отдельный
элемент.
Возвращаясь к моей "аналогии с однофамильцами", вы передаёте какой-то
"список фамилий" и ещё одну фамилию отдельно.
Но я не понял - что функция должна делать и что возвращать?
Судя по первой строке функции из вашего примера входящий "список фамилий"
по-любому пополняется ещё одной переданной отдельной фамилией - ar.push(a);.
А что функция тогда должна ЕЩЁ делать и что возвращать? | |
|
|
|
|
|
|
|
для: АЯ
(07.12.2009 в 18:37)
| | при вызове if(arrayUnique(ar, a)), передаётся два параметра ar - пустой массив и a - элемент(string), которыми заполняется массив в функции arrayUnique(): ar.push(a)
Этот вызов - if(arrayUnique(ar, a)) - происходит в цикле for, то есть массив ar заполняется элементами a.
Во время заполнения массива ar мы должны брать текущее значение a и проверять есть ли такое же в массиве ar. Если есть, то возвращать false, если его нет, то возвращать true.
Сейчас понятно или нет? :) | |
|
|
|
|
|
|
|
для: HelloMoto
(07.12.2009 в 18:46)
| | Так, вроде бы понял.
Вам по-любому надо Иванова к списку добавить, но при этом сообщить - первый
ли это Иванов в списке или же у него же были однофамильцы в этом списке.
Ну это вы и сами можете сделать:
1. или циклом перебирайте весь массив и сравнивайте с новым элементом; как
только встретите Иванова, так и выходите из цикла брейком (чтобы третьих и
четвертых "ивановых" не искать)
2. или преобразуйте массив в строку (с каким-то уникальным
разделителем) + добавьте этот же разделитель в начало и конец и методом
search () ищите совпадение в этой строке
с RegExp = 'разделитель' + новый_элемент + 'разделитель';.
Но это много медленнее первого варианта.
---
Кстати, зря вы "упёрлись" в метод push () - он тормозной. Запустите:
<script>
var s = [1, 2, 3], d = 4;
function arrayUnique (ar, a) {ar.push (a)}
function faster (ar, a) {ar [ar.length] = a}
var T1 = new Date ().valueOf (); for (var j = 0; j < 98765; j++) arrayUnique (s, d);
var T2 = new Date ().valueOf (); for (var j = 0; j < 98765; j++) faster (s, d);
var T3 = new Date ().valueOf ();
alert ('push () работает ~ в ' + (T2 - T1) / (T3 - T2) + ' раза медленнее');
</script>
| и удостоверьтесь. | |
|
|
|
|
|
|
|
для: АЯ
(07.12.2009 в 19:09)
| |
...
for(...){
if(arrayUnique(projects, project)){...}
}
...
function arrayUnique(projects, project) {
var isExist;
projects [projects.length] = project;
for(var i=0; i <= projects.length; i++){
if(projects[i] == project){
isExist = false;
break;
} else {isExist = true;break;}
}
return isExist;
}
|
С каждым вызовом arrayUnique в цикле for массив projects заполняется разными значениями - как одинаковыми, так и нет. Что-то не то.. работает некорректно :(
Что не так? туплю...
Мне надо возвращать true только тогда, когда текущего значения в массиве нет. Как изменить моё условие, оно неверное, я вижу ) | |
|
|
|
|
|
|
|
для: HelloMoto
(07.12.2009 в 22:01)
| | текущее значение всегда будет в массиве. вы проверяйте сначала, а потом добавляйте его.
перенесите в конец функции projects [projects.length] = project; | |
|
|
|
|
|
|
|
для: HelloMoto
(07.12.2009 в 22:01)
| |
function arrayUnique (projects, project)
{
for (var r = true, j = 0, l = projects.length; j < l; j++)
if (projects [j] == project) {r = false; break}
projects [l] = project; return r;
}
//для проверки
var pros = ['Иванов', 'Петров', 'Сидоров', 'Кузнецов'];
var pro_1 = 'Иванов'; //имеется
var pro_2 = 'Шариков'; //уникальное
alert (arrayUnique (pros, pro_1)); //false для Иванова
alert (arrayUnique (pros, pro_2)); //true для Шарикова
|
| |
|
|
|
|
|
|
|
для: АЯ
(07.12.2009 в 23:20)
| | Да, всё ОК!
Спасибо, AlexSol.
Отдельное спасибо вам, АЯ! Спасибо, что вы есть! :) | |
|
|
|
|
|
|
|
для: HelloMoto
(08.12.2009 в 13:36)
| | Эх.. всё же ещё вопросик..
а как здесь
for (var r = true, j = 0, l = projects.length; j < l; j++)
if (projects [j] == project) {r = false; break}
projects [l] = project; return r;
|
можно заюзать hashmap вместо массива? Ну чтобы не по массиву бегать, а по hashmap... | |
|
|
|
|
|
|
|
для: HelloMoto
(08.12.2009 в 14:29)
| | Если изначально (в первый раз) передаваемый массив будет у вас пустым, то можно.
Но hashmap нужен будет глобальный - до первого обращения к функции вам надо его объявить.
<script>
var H = new Array ();
//...
function arrayUnique (projects, project)
{
var r = (!H [project]) ? true : false; H [project] = 9;
projects [projects.length] = project; return r;
}
//вызов функции arrayUnique ()
|
| |
|
|
|
|
|
|
|
для: АЯ
(08.12.2009 в 15:54)
| | АЯ, ммм... не совсем то..
Надо заюзать вот это: var hash = {};, где по ключу будем искать.... так как текущий вариант медленно работает из-за поиска в массиве.... | |
|
|
|
|
|
|
|
для: HelloMoto
(09.12.2009 в 14:53)
| | Вы разберитесь с "текущим вариантом" (с последним кодом) - там как раз ищется по ключу.
И ваш var hash = {}; - он уже "заюзан" как var H = new Array ();
И работает всё как раз быстро как только можно - никакого "поиска по массиву" нет. | |
|
|
|
|
|
|
|
для: АЯ
(09.12.2009 в 16:36)
| | Да, точно!
АЯ, Большое-прибольшое Вам Спасибо!!! :) | |
|
|
|