Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как создать в объекте свойство с заранее неизвестным именем (http://www.flasher.ru/forum/showthread.php?t=208081)

SvetozarPNZ 03.06.2014 11:08

Как создать в объекте свойство с заранее неизвестным именем
 
Моя задача состоит в создании ассоциативного массива, в котором имя каждого ключа генерируется программой. В справочнике нашел у класса Object такой метод
Код AS3:

setPropertyIsEnumerable

Как я понимаю, он создает свойство с динамическим именем, но здесь ничего не трассируется

Код AS3:

 
var obj:Object = new Object();
var str:String = 'любая строчка';
 
obj.setPropertyIsEnumerable(str, true);
 
for (var prop in obj) {
trace(prop)
}

Либо я неправильно понимаю назначение метода, либо у меня что-то в коде не то.
Подскажите, как создать для объекта свойство с динамическим именем.

Будут вопросы, зачем все это.
Заранее пишу:
1. Я собираю ссылки с загруженных веб-страниц.
2. Для проверки уникальности ссылок я сохраняю их в массив.
3. Для ускорения алгоритма проверки (ссылок может быть много миллионов) я пробую сортировать массив или использовать ассоциативный массив.
4. Я хочу в ключи ассоциативного массива записывать ссылки, чтобы быстрый доступ к ним осуществлял сам язык.

alexandrratush 03.06.2014 11:30

Может стоит использовать класс Dictionary?

Код AS3:

import flash.utils.Dictionary;
 
var dictionary:Dictionary = new Dictionary();
        dictionary["prop1"] = "Hello";
        dictionary["prop2"] = "world!";
 
trace(dictionary["prop1"]);
trace(dictionary["prop2"]);

Или использовать обычный массив со строками-ключами, тут почитать можно.

elder_Nosferatu 03.06.2014 11:32

Код AS3:

var obj:Object = new Object();
var str:String = 'любая строчка';
 
obj[str] = true;
 
for (var prop in obj) {
trace(prop)
}


SvetozarPNZ 03.06.2014 11:37

Цитата:

Сообщение от alexandrratush (Сообщение 1167263)
Может стоит использовать класс Dictionary?

А чем он лучше Object, что вы его решили предложить?

Цитата:

Сообщение от alexandrratush (Сообщение 1167263)
Код AS3:

        dictionary["prop1"] = "Hello";
        dictionary["prop2"] = "world!";


Здесь имена ключей prop1 и prop2, а мне нужно динамическое любое имя. Или вы что-то другое имеете в виду?..

Добавлено через 5 минут
Цитата:

Сообщение от elder_Nosferatu (Сообщение 1167264)
Код AS3:

var obj:Object = new Object();
var str:String = 'любая строчка';
 
obj[str] = true;
 
for (var prop in obj) {
trace(prop)
}


После таких простых решений чувствую себя тупым.
Спасибо!

alexandrratush 03.06.2014 11:49

Цитата:

Сообщение от SvetozarPNZ (Сообщение 1167265)
Здесь имена ключей prop1 и prop2, а мне нужно динамическое любое имя. Или вы что-то другое имеете в виду?..

Код AS3:

import flash.utils.Dictionary;
 
var str:String = "любая строчка";
 
var dictionary:Dictionary = new Dictionary();
        dictionary["prop1"] = "Hello";
        dictionary[str] = "world!";
 
trace(dictionary["любая строчка"]);                //world!
trace(dictionary[str]);                                        //world!

Это не то что вам нужно?

elder_Nosferatu 03.06.2014 11:51

Цитата:

Сообщение от alexandrratush (Сообщение 1167263)
Может стоит использовать класс Dictionary?

А смысл? Объект использует строковые ключи, словарь же - это навороченый объект, для которого ключем может служить любой объект. Зачем платить больше?

Цитата:

Сообщение от SvetozarPNZ (Сообщение 1167261)
Будут вопросы, зачем все это.
Заранее пишу:
1. Я собираю ссылки с загруженных веб-страниц.
2. Для проверки уникальности ссылок я сохраняю их в массив.
3. Для ускорения алгоритма проверки (ссылок может быть много миллионов) я пробую сортировать массив или использовать ассоциативный массив.
4. Я хочу в ключи ассоциативного массива записывать ссылки, чтобы быстрый доступ к ним осуществлял сам язык.

Судя по написаному вам нужна просто коллекция ссылок, а не упорядоченый массив ссылок. Какая разница, как ссылки расположены, главное, что они сохранены. В качестве колекции достаточно обычного объекта, ключами которого будут сами ссылки. А значения и вовсе не нужны - хоть true, хоть false, да хоть 666.
Код AS3:

var collection:Object = { };
collection[url_0] = true;
collection[url_1] = false;
collection[url_2] = 666;
collection[url_3] = null;
...
for (var url:String in collection) {
        trace(url, "- важные данные, а", collection[url], "- просто мусор...");
}

К стати, так вы решите вопрос уникальности без сортировки. Если попадутся две одинаковые ссылки, то они все равно будут единственным свойством объекта collection.

alexandrratush 03.06.2014 11:59

Цитата:

Сообщение от elder_Nosferatu (Сообщение 1167268)
А смысл? Объект использует строковые ключи, словарь же - это навороченый объект, для которого ключем может служить любой объект. Зачем платить больше?

Не спорю. Упустил я момент что ТС нужно использовать строковый ключ. :)

SvetozarPNZ 03.06.2014 12:10

Судя по всему такое обращение к свойству obj[currentLink] перебирает все свойства объекта и не обеспечивает хорошей скорости работы скрипта. Значит сортировать будем.

ChuwY 03.06.2014 12:14

Цитата:

Сообщение от SvetozarPNZ (Сообщение 1167272)
Судя по всему такое обращение к свойству obj[currentLink] перебирает все свойства объекта и не обеспечивает хорошей скорости работы скрипта. Значит сортировать будем.

Потому что нужно обращаться вот так:
Код AS3:

if(currentLink in obj) {
  doSomething();
}


SvetozarPNZ 03.06.2014 12:19

Цитата:

Сообщение от elder_Nosferatu (Сообщение 1167268)
Судя по написаному вам нужна просто коллекция ссылок, а не упорядоченый массив ссылок. Какая разница, как ссылки расположены, главное, что они сохранены.

Все верно. Есть у меня идейка алгоритма, при котором проверка уникальности будет быстрой, но нужно, чтоб массив сортировался на лету. Т.е. в него ссылки добавлялись уже в алфавитном порядке.

Представьте миллиард ссылок. Как быстро проверить на уникальность новой тысячи? Для каждой перебирать весь миллиард?..

Добавлено через 2 минуты
Цитата:

Сообщение от ChuwY (Сообщение 1167273)
Потому что нужно обращаться вот так:
Код AS3:

if(currentLink in obj) {
  doSomething();
}


Я так и обращался. Суть не меняется. Я уверен, что перебираются все свойства при запросе какого-то одного. Не знаю, как доказать, но 1500 ссылок за 15 секунд... Тут попахивает гребанным числом итераций.

Добавлено через 8 минут
Немножко приврал. Вот моя проверка
Код AS3:

if (!obj[currentLink]) obj[currentLink] = true;

А ваш пример не работает. Он ищет свойство с именем currentLink.

ChuwY 03.06.2014 12:33

Ваша проверка делает абсолютно то же самое.
Только утверждение там обратное. "Если такого свойства нет".
И скорость гораааздо больше, чем вы пишете.
И нет. Там не перебор.

SvetozarPNZ 03.06.2014 12:45

Цитата:

Сообщение от alexandrratush (Сообщение 1167263)
Или использовать обычный массив со строками-ключами, тут почитать можно.

Почитал. Там были объекты, о которых я и сам спрашиваю, словари, как расширение объектов, а про массивы там написано

Код AS3:

Использование конструктора Array для создания ассоциативного массива не дает никаких особых преимуществ.

Задаюсь вопросом, зачем вы это советуете :)

elder_Nosferatu 03.06.2014 12:46

На знаю как далеко зашли в оптимизации сортировки массивов, но те методы, которые я учил на уроках информатики в школьные годы не назовешь очень быстрыми... Короче, трудовой мозоль на пятой точке подсказывает мне, что плеер быстрее найдет свойство обьекта своими методами, чем вы будете его из-под палки заставлять сортировать ничем ему не интересный массив. Да и поиск свойства осуществляется максимум полным пребором все имеющихся свойств, а сортировку массива за один проход не сделаешь :(. Плюс поиск предполагает только операцию сравнения, а сортировка - кроме сравнения еще и присваивание значения.

SvetozarPNZ 03.06.2014 12:48

Цитата:

Сообщение от ChuwY (Сообщение 1167277)
И нет. Там не перебор.

Блин, точно не перебор. А так долго выполняет... Значит, как бы я не исхищрялся, все равно быстрее, чем мгновенный доступ к свойству я не придумаю... Эх!

ChuwY 03.06.2014 12:55

Совсем не долго выполняет.
Видимо, ошибка где-то еще.
Покажите ваш код.

SvetozarPNZ 03.06.2014 12:56

Цитата:

Сообщение от elder_Nosferatu (Сообщение 1167280)
На знаю как далеко зашли в оптимизации сортировки массивов, но те методы, которые я учил на уроках информатики в школьные годы не назовешь очень быстрыми... Короче, трудовой мозоль на пятой точке подсказывает мне, что плеер быстрее найдет свойство обьекта своими методами, чем вы будете его из-под палки заставлять сортировать ничем ему не интересный массив. Да и поиск свойства осуществляется максимум полным пребором все имеющихся свойств, а сортировку массива за один проход не сделаешь :(. Плюс поиск предполагает только операцию сравнения, а сортировка - кроме сравнения еще и присваивание значения.

На хабре пописывают про методики, обгоняющие стандартные методы ActionScript.
Говоря о сортировки я не имел в виду стандартных методов. У меня немножко другой подход со схожими алгоритмами.
В программе появилась ссылка, ее нужно по алфавиту вставить в массив (не сортировать весь массив! он уже сортируется в процессе сбора ссылок). Чтобы найти место для ссылки в сортированном индексном массиве из 1 млрд элементов достаточно 40 итераций. Или, как я выше выяснил, всего 1 проверку в ассоциативном массиве.

Чтобы собрать 1 млрд ссылок, нужно проводить проверки 115 суток...:wacko:

Добавлено через 1 минуту
Цитата:

Сообщение от ChuwY (Сообщение 1167282)
Совсем не долго выполняет.
Видимо, ошибка где-то еще.
Покажите ваш код.

Код AS3:

package 
{
 
        import flash.display.MovieClip;
        import flash.events.MouseEvent;
 
        public class Main extends MovieClip
        {
 
                var startBut;
                var links;
                var massiv;
                var massLink = [];
                var obj:Object = new Object();
                var e;
 
                public function Main()
                {
                        startBut = getChildByName('start');
                        startBut.addEventListener(MouseEvent.CLICK, writeMassiv);
 
                        links = getChildByName('links1');
                        massiv = getChildByName('massiv1');
                }
                public function writeMassiv(e)
                {
 
                        while (links.text)
                        {
                                var currentLink:String = links.text.substring(0,links.text.indexOf('\r'));
                                links.text = links.text.substr(links.text.indexOf('\r') + 1);
                                massiv.text +=  currentLink + '\r';
                                if (!obj[currentLink]) obj[currentLink] = true
                                else (trace(currentLink, '- такая ссылка есть');
                        }
                        if (! links.text)
                        {
                                trace('ссылок нет');
                        }
 
                }
        }
}


GBee 03.06.2014 13:13

Цитата:

Я уверен, что перебираются все свойства при запросе какого-то одного
Так попробуйте. Вообще-то эту схему используют, как кеш/хеш довольно часто. На 3000 свойств у меня моментально обращение проходит. Без всяких сортировок.

ChuwY 03.06.2014 13:23

Ну вы же понимаете, наверное, что в приведенном вами коде indexOf и substring кушают раз в 100 больше времени, чем поиск свойства?
А с учетом количества их вызовов...
Вот вам другой простенький тест.
(хотя тут генерация ключа более-менее жручая)

Код AS3:

package
{
        import flash.display.Sprite;
 
        public class test2 extends Sprite
        {
                private static const NUM_KEYS:int = 150000;
 
                private var _hash:Object = {};
                public function test2()
                {
                        fill();
 
                        check();                       
                }
 
                private function check():void
                {
                        for(var i : int = 0; i < NUM_KEYS; i++) {
                                var key:String = generateKey();
 
                                if(key in _hash) {
                                        trace("bingo! " + key + " exist");
                                }
                        }
                }
 
                private function fill():void
                {
                        for(var i : int = 0; i < NUM_KEYS; i++) {
                                var key:String = generateKey();
 
                                _hash[key] = true;
                        }
                }
 
                private function generateKey():String
                {
                        var key:String = "";
 
                        for(var i : int = 0; i < 3; i++) {
                                key += int(Math.random() * 100);
                        }
 
                        return key;
                }
        }
}


toFL 03.06.2014 13:48

SvetozarPNZ, запомните:
Цитата:

Вызов функции всегда дороже операторов.

SvetozarPNZ 03.06.2014 14:07

Понятно. Запомнил. Мне все равно нужно какие-то времязатратные действия производить. Буду смотреть, оптимизировать остальное.

LifeIsRhythm 03.06.2014 14:32

SvetozarPNZ, мне кажется Вам не as3 нужен. Какие миллиард ссылок и ассоциативный массив:) Мне кажется, что плеер даже на миллионе ссылок, которые парсятся из какого-то файла ( xml или json с миллионом ссылок плеер не потянет ) + запихнуть это всё в массив... Что конкретно Вы хотите?

Добавлено через 4 минуты
Если вы хотите, чтобы обрабатывалось все на клиенте, то сохраняйте ссылки на сервере, где они будут разбиваться на маленькие порции, во флеше определяйте, к какой порции относится ссылка и грузите этот кусок. Сюреализуйте json в объект и уже в нем ищите.

Добавлено через 23 минуты
Не знаю, что Вы подразумеваете под словами "записывать ссылки в качестве ключа", но есть способ, который переведет ссылки с типом String в тип int, даже можно ограничивать длину ключа.
И помните, что ссылки бывают более чем 500 символов.


Часовой пояс GMT +4, время: 22:22.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.