PDA

Просмотр полной версии : Возможно ли, не имея ссылки на объект, получить этот объект из массива


HardCoder
14.03.2012, 22:13
Здравствуйте. Есть вектор:var myObjects:Vector.<Object> = new <Object> [new Object4(), new Object2(), new Object8()];Заранее известно, что в этом векторе все типы элементов разные (то есть не может быть 2 элемента с типом Object2). Мне необходимо получить элемент массива с типом Object2 (то есть 2-й элемент). Я - разработчик знаю что один экземпляр Object2 точно есть в этом массиве. Как заставить программу узнать это?
Исходные данные: тип искомого объекта (класс Object2) и сам массив с этим объектом. Больше у нас ничего нет. Подскажите, пожалуйста, возможно ли программно найти этот объект в массиве по его классу?

Добавлено через 1 минуту
PS: Может лучше использовать Dictionary?

Добавлено через 6 минут
Во я затупил! Можно пройтись по массиву и у каждого элемента спросить: он is Object2, или нет. Но может есть более продвинутые решения?

anmelegov
14.03.2012, 22:28
for each (var object:Object in myObjects) {
if (object is Object2) {
break;
/// поиск окончен
}
}


Добавлено через 31 секунду
блин не дочитал до конца =)

HardCoder
14.03.2012, 22:38
anmelegov, спасибо, что откликнулся. Об этом и сам подумываю. Только вот не нравится мне такой вариант. Дело в том, что мне в разных частях проекта часто придется выдергивать то Object2, то SomeClass234 и др. И все время потрошить массив, как-то... Думал спрошу здесь, мож у кого более приятные идеи появятся.

Добавлено через 42 секунды
PS: где-то читал, что for быстрее чем for each, вот и всегда использую первый

Psycho Tiger
14.03.2012, 22:39
anmelegov, поиск окончен будет после цикла for each.

anmelegov
14.03.2012, 22:44
for быстрее, for each в каждой итерации будет записывать object, а запись в память всегда тормозит

Bgg
14.03.2012, 23:06
for быстрее, for each в каждой итерации будет записывать object, а запись в память всегда тормозит

Проверяли? Наверно на 100 млн. объектах быстрее?

anmelegov
14.03.2012, 23:09
Проверяли? Наверно на 100 млн. объектах быстрее?

не проверял... да скорее всего разница мало ощутима =)

Inet_PC
14.03.2012, 23:50
indexOf, не? Не дочитал, сори. filter как вариант.

Aquahawk
14.03.2012, 23:53
я бы посоветовал вам сделать Dictionary если уж так важно имеет отношение Class->object. Если вам нужен именно массив чтоб им ещё как-то пользоваться оставьте его, а параллельно ему сделайте Dictionary где ключом будет класс а значением объект.

Добавлено через 1 минуту
Это в случае если ваши классы инстанцируются не один раз, а если один раз то можно вообще классического синглтона замутить со статическим getInstance() который один раз создаст объект и сохранит его в статическом поле, в потом его и будет возвращать.

HardCoder
15.03.2012, 00:08
Да - отношение именно Class->object. Не особо важно, массив это или еще что-то - главное список объектов, которые можно вытащить. А вот с синглтоном немного не понятно... У меня сейчас есть статический вектор с экземплярами. Он не меняется никогда...

Aquahawk
15.03.2012, 01:01
У вас может быть несколько таких объектов одного класса? Т.е. в разных частях программы разные такие списки с разными объектами одних и тех же классов? Если да, то dictionary лучший вариант.
А если от каждого класса создаётся только один объект, то это синглтон, и можно хранить ссылку на объект в самом классе. Вот так
package {
public class Singleton {
public function Singleton() {
}

private static var _instance:Singleton;

public static function get instance():Singleton {
if (!_instance) _instance = new Singleton();
return _instance;
}
}
}

Добавлено через 1 минуту
и пользовать соответственно потомSingleton.instance.

HardCoder
15.03.2012, 01:19
Aquahawk, большое спасибо за информацию. Я знаю что такое синглтон :). Только не совсем понимаю какая мне разница - хранить список в синглтоне или как статический массив в каком-нибудь служебном классе.
Например я оперирую 10-ю разными классами. Список только один. В этом списке по одному объекту каждого из этих 10-ти классов. Они не повторяются в списке. Я создал массив этих 10-ти экземпляров. Сделал этот массив как статическое свойство некоего класса. Именно статическое, так как этот список мне понадобится в любой момент и неизвестно где. Да - можно сделать синглтон, но суть не изменится от этого.
А вот за пример с Dictionary - был бы вам очень благодарен. Читал в справке про эти словари - но там слишком скудно написано и всегда бросал эту затею, так как не совсем понятно что это такое и как его юзать..

Aquahawk
15.03.2012, 01:31
package {
import flash.display.Sprite;
import flash.utils.Dictionary;

public class Main extends Sprite {

private var _dic:Dictionary;

public function Main():void {
this._dic = new Dictionary();
this._dic[ExampleClass1] = new ExampleClass1();
this._dic[ExampleClass2] = new ExampleClass2();
this._dic[ExampleClass3] = new ExampleClass3();

test1();
test2();
test3();
}

public function test1():void {
(_dic[ExampleClass1] as ExampleClass1).test();
}

public function test2():void {
(_dic[ExampleClass2] as ExampleClass2).test();
}

public function test3():void {
(_dic[ExampleClass3] as ExampleClass3).test();
}
}
}

class ExampleClass1 {
public function test():void {
trace("obj1");
}
}

class ExampleClass2 {
public function test():void {
trace("obj2");
}
}

class ExampleClass3 {
public function test():void {
trace("obj3");
}
}

Добавлено через 3 минуты
Dictionary это таблица где ключами являются сами объекты, выражаясь в терминах низкоуровневых языков, ключом является адрес ключевого объекта, а значение тоже объект. Но поскольку в as класс представлен в рантайме в виде объекта типа Class то всё хорошо работает.

Добавлено через 5 минут
А хранить я вам предлагал не список в синглтоне, а вообще не делать список. Если у вас десять таких классов то сделать каждого из них синглтоном и пусть он сам себе ссылку на свой объект и хранит. Вообще без списка, нужен объект этого класса, у него и взяли.

Добавлено через 6 минут
но словарь лучше, больше возможности для расширения.

HardCoder
15.03.2012, 01:44
Aquahawk, спасибо большое. То есть, если у меня есть список экземпляров некоторых классов, то с помощью дикшнери я могу вытащить любой экземпляр по названию класса?
this._dic = new Dictionary();
this._dic[ExampleClass1] = new ExampleClass1();
this._dic[ExampleClass2] = new ExampleClass2();
this._dic[ExampleClass3] = new ExampleClass3();
trace(_dic[ExampleClass1]);
Тогда мне в данном случае это подходит.
Только вот интересно, что будет если объекты повторятся?this._dic = new Dictionary();
this._dic[ExampleClass1] = new ExampleClass1();
this._dic[ExampleClass2] = new ExampleClass2();
this._dic[ExampleClass2] = new ExampleClass2();
trace(_dic[ExampleClass2]);

Aquahawk
15.03.2012, 01:54
this._dic[ExampleClass2] = new ExampleClass2(); // создали объект и записали по этому ключу
this._dic[ExampleClass2] = new ExampleClass2(); // создали второй объект и записали по этому же ключу
в результате этих двух строк в словаре будет одна запись с одним объектом, последним. Ссылка на тот объект который был там до этого будет потеряна и объект будет съеден GC если на него больше нет нигде ссылок. Короче дважды создадим объект, но в словаре окажется только последний. Если хочестся много объектов, то можно сгородить словарь векторов.

HardCoder
15.03.2012, 01:56
Ага, ну тогда спасибо. Тема исчерпана - движемся в сторону словарей...

Aquahawk
15.03.2012, 01:58
package {
import flash.display.Sprite;
import flash.utils.Dictionary;

public class Main extends Sprite {

private var _dic:Dictionary;

public function Main():void {
this._dic = new Dictionary();
this._dic[ExampleClass1] = new Vector.<ExampleClass1>();
(this._dic[ExampleClass1] as Vector.<ExampleClass1>).push(new ExampleClass1());
(this._dic[ExampleClass1] as Vector.<ExampleClass1>).push(new ExampleClass1());

this._dic[ExampleClass2] = new Vector.<ExampleClass2>();
(this._dic[ExampleClass2] as Vector.<ExampleClass2>).push(new ExampleClass2());
(this._dic[ExampleClass2] as Vector.<ExampleClass2>).push(new ExampleClass2());
(this._dic[ExampleClass2] as Vector.<ExampleClass2>).push(new ExampleClass2());

this._dic[ExampleClass3] = new Vector.<ExampleClass3>();
(this._dic[ExampleClass3] as Vector.<ExampleClass3>).push(new ExampleClass3());

this.test1();
this.test2();
this.test3();
}

public function test1():void {
for each (var exObj:ExampleClass1 in this._dic[ExampleClass1]) {
exObj.test();
}
}

public function test2():void {
for each (var exObj:ExampleClass2 in this._dic[ExampleClass2]) {
exObj.test();
}
}

public function test3():void {
for each (var exObj:ExampleClass3 in this._dic[ExampleClass3]) {
exObj.test();
}
}
}
}

class ExampleClass1 {
public function test():void {
trace("obj1");
}
}

class ExampleClass2 {
public function test():void {
trace("obj2");
}
}

class ExampleClass3 {
public function test():void {
trace("obj3");
}
} вот так если много хочется

Psycho Tiger
15.03.2012, 11:35
this._dic[ExampleClass1] = new Vector.<ExampleClass1>();
(this._dic[ExampleClass1] as Vector.<ExampleClass1>).push(new ExampleClass1());
(this._dic[ExampleClass1] as Vector.<ExampleClass1>).push(new ExampleClass1());

this._dic[ExampleClass2] = new Vector.<ExampleClass2>();
(this._dic[ExampleClass2] as Vector.<ExampleClass2>).push(new ExampleClass2());
(this._dic[ExampleClass2] as Vector.<ExampleClass2>).push(new ExampleClass2());
(this._dic[ExampleClass2] as Vector.<ExampleClass2>).push(new ExampleClass2());

this._dic[ExampleClass3] = new Vector.<ExampleClass3>();
(this._dic[ExampleClass3] as Vector.<ExampleClass3>).push(new ExampleClass3());

Ужас какой. А ссылки на что?

Aquahawk
15.03.2012, 11:52
Psycho Tiger писал в час ночи копипастом чисто чтоб показать идею. Согласен что ужас.