Просмотр полной версии : Массив самостоятельно сортируется
Упёрся в нерешаемую проблему — флеш самостоятельно сортирует массив, причём в непонятном мне порядке.
var test:Array = new Array();
test[0] = 2760;
test[1] = 5770;
test[2] = 5130;
test[3] = 5199;
test[4] = 1000;
var test2:Array = new Array();
for (var obj:String in test) {
trace(obj + " " + test[obj]); // просматриваю исходный массив
test2[test[obj]] = test[obj];
}
trace();
for (var obj2:String in test2) {
trace(obj2 + " " + test2[obj2]); // сравниваю со вторым
}
Результат trace:
// исходный массив
0 2760
1 5770
2 5130
3 5199
4 1000
// получившийся массив
2760 2760
1000 1000
5770 5770
5130 5130
5199 5199
Т.е. "1000" вдруг перепрыгнула. Подскажите, пожалуйста, где я натупил?
Волгоградец
15.04.2010, 17:38
Цикл for in берет элементы не по порядку, т.к. свойства объекта не хранятся по порядку, а случайным образом. Используйте for.
Обычно они в обратном порядке идут)
for each, как я понимаю, действует по тому же принципу? Зачем такая грабля вообще нужна? Кому вдруг понадобится случайным образом выбирать элементы массива?
for не могу применять, т.к. у меня не все элементы заполнены. Т.е. типа такого:
user[123]['name'] = "Petya"
user[123]['surname'] = "Ivanov"
user[427]['name'] = "Vanya"
user[427]['surname'] = "Sidorov"
Добавлено через 33 секунды
Обычно они в обратном порядке идут)
Как я уже показал в примере — они идут в необъяснимом порядке :) Если добавить побольше элементов — там вообще трешняк получается.
for не могу применять, т.к. у меня не все элементы заполнены. Т.е. типа такого:
Пропускайте пустые элементы.
if(array[iter])
{
//ода, элемент есть
}
И for each это не грабля. Не всегда нужно перебирать массив по порядку.
1. Почему тогда в первом случае массив проходится в нужном порядке, а глючит лишь второй?
2. Проблема в том, что у меня разброс айдишников от 1 до 50 миллионов.
Кому вдруг понадобится случайным образом выбирать элементы массива?Это не элементы массива, это свойства объекта.
for..in
Выполняет итерацию через динамические свойства объекта или элементы массива и выполняет инструкцию statement для каждого свойства или элемента. Свойства объекта не хранятся в определенном порядке, поэтому могут отображаться в произвольной последовательности.
*запутался*
Допустим, свойства объекта идут в произвольном порядке. Но причём тут объекты, если речь идёт о массивах?
Понял.
Я правильно понимаю, что последовательно пройти по массиву-объекту можно лишь используя for?
После других языков программирования это звучит удивительно нереально.
Всем спасибо за помощь, буду думать как пролезть другим путём :)
Добавлено через 30 минут
Решил всё-таки покопаться дальше.
Для чего тогда существуют методы сортировки элементов массива, если они выводятся в случайном порядке? Это противоречит вашим словам, что они выводятся в произвольном порядке.
для того чтобы можно было сделать так:
for (var i:uint = 1; i < array.length; i++)
trace(array[i]);
Так — это вывести всё в первоначальном варианте? Сортировка в таком случае не будет учтена.
На всякий случай напомню про ассоциативные массивы. for решает лишь в определённых случаях, когда нумерация инкрементная без пробелов, в остальных используется for each (for ... in).
Psycho Tiger
15.04.2010, 22:24
У вас каша в голове. Во флеше массивы это не честные массивы.
for in гуляет по памяти, нашел - ага! Это элемент массива! Давай ка его - отсюда и случайный порядок.
А порядок в массиве задается его индексом - сортировка сортирует элементы так, чтобы, например, наименьшее число было с самым мелким индексом.
И тогда при прямом проходе массива
for (var i:uint = 1; i < array.length; i++)
trace(array[i]);
выведутся значения по возрастанию, но память как была кашей, так и идёт.
Дык каша и возникла из-за того, что флеш работает с массивами как-то слишком по-своему.
Как я понял из экспериментов — он слабо разбирается что такое ключи и ассоциативные массивами. Если работать лишь со значениями — всё в порядке. Но тогда страдает вычислительная часть.
Если брать свой пример выше:
user[123]['name'] = "Petya"
user[123]['surname'] = "Ivanov"
user[427]['name'] = "Vanya"
user[427]['surname'] = "Sidorov"
Такой массив должен выглядеть так:
user[0]['id'] = 123;
user[0]['name'] = "Petya"
user[0]['surname'] = "Ivanov"
user[1]['id'] = 427
user[1]['name'] = "Vanya"
user[1]['surname'] = "Sidorov"
Получается, если юзер 427 поменяет имя, то мне надо каждый раз искать такую запись.
Зачем ты в качестве ключа указываешь какое-то число? Пихай его тоже в объект:
var user:User = new User();
user.id = 427;
user.name = "Petya";
user.surname = "Ivanov";
users.push(user);
//Сортировка по id
users.sortOn("id");
//Проход по сортированному массиву
for (var i:int =0; i < users.length; i++){
var user:User = users[i];
}
...
//Дополнительный класс пользователя
class User extends Object{
public var id:int;
public var name:String;
public var surname:String;
}
По простому: Ассоциативные массивы = объект != массив. Ты когда for...in'ом проходишься по всем свойствам объекта - ты надеешься получить их в том порядке котором ты их отсортировал? Я лично не умею сортировать свойства объекта.
Как в этом случае взять конкретного юзера по id?
Перебирать весь массив для поиска объекта с нужным id?
Тут надо решить что важнее: быстрый доступ - тогда будет хэш-список или сортировка (массив).
Так можно совместить приятное с полезным: сделать один обычный массив, а другой ассоциативный.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.