2016-01-25 2 views
1

У меня есть упорядоченная коллекция, которую я бы хотел преобразовать в литерал массив. Ниже упорядоченная коллекция и желаемый результат, соответственно:Преобразование упорядоченной коллекции в литературный массив

an OrderedCollection(1 2 3)
#(1 2 3)

Что будет наиболее эффективным способом для достижения этой цели?

ответ

6

сообщение asArray будет создавать и Array из OrderedCollection:

anOrderedCollection asArray 

и это, вероятно, что вы хотите.

Однако, учитывая, что вы говорите, что хотите литеральный массив , возможно, вы ищете строку '#(1 2 3)'. В этом случае я хотел бы использовать:

^String streamContents: [:stream | aCollection asArray storeOn: stream] 

где aCollection ваш OrderedCollection.

Если вы еще не знакомы с streamContents:, это может быть хорошей возможностью изучить его. Что она делает в этом случае эквивалентно:

stream := '' writeStream. 
    aCollection asArray storeOn: stream. 
    ^stream contents 

в том смысле, что она захватывает образец:

stream := '' writeStream. 
    <some code here> 
    ^stream contents 

который является довольно распространенным в Smalltalk.

UPDATE

Может быть, это помогло бы, если мы выясняем немного то, что мы подразумеваем буквенные массивы в Smalltalk. Рассмотрим следующие два метода

method1 
    ^Array with: 1 with: 2 with: 3 

method2 
    ^#(1 2 3) 

Оба метода ответа с того же массива, один с записями 1, 2 и 3. Однако две реализации различны. В method1 массив создается динамически (т. Е. Во время выполнения). В method2 массив создается статически (т. Е. Во время компиляции). Фактически, когда вы принимаете (и, следовательно, компилируете) method2, массив создается и сохраняется в методе. Вместо этого в method1 нет массива, и результат создается каждый раз при вызове метода.

Следовательно, вам нужно было бы создать строку '#(1 2 3)' (т. Е. Буквальное представление массива), если бы вы динамически генерировали код Smalltalk.

+0

I _hope_ 'asArray' - это все, что вы хотите - мне может быть интересно узнать, зачем вам нужна строка, иначе :) – mgarciaisaia

+0

@mgarciaisaia Да, я просто понял, что вы говорите и изменил мой ответ. –

5

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

Однако, я считаю, вы просто не поняли, что означает буквальный массив, и вы инфакт просто ищете массив.

Литеральный массив - это массив, который (в Pharo и Squeak [1]) создается во время компиляции, то есть когда вы принимаете метод.

Чтобы превратить упорядоченную коллекцию в массив, вы используете asArray.

Просто проверить результаты

#(1 2 3). 
(OrderedCollection with: 1 with: 2 with: 3) asArray. 

Вы увидите, что оба равны.

[1]: смотрите здесь для объяснения: https://stackoverflow.com/a/29964346/1846474

+0

Благодарим за редактирование @ bert-freudenberg. – eMBee

+0

@bert, хотя я удивляюсь, разве не факт, что во время компиляции создается литерал массив детали реализации? поскольку http://stackoverflow.com/a/29964346/1846474 объясняет, что важно то, что мы не можем полагаться на литеральные массивы, создающие отдельные объекты или нет. – eMBee

1

В Pharo 5.0 (бета-версия), вы можете сделать:

| oc ary | 
oc := OrderedCollection new: 5. 
oc addAll: #(1 2 3 4 5). 
Transcript show: oc; cr. 
ary := oc asArray. 
Transcript show: ary; cr. 

Выход на стенограммы:

an OrderedCollection(1 2 3 4 5) 
#(1 2 3 4 5) 
0

кодировка literalArray - это своего рода кодировка стойкости «бедный человек», чтобы получить представление, которое может восстановить объект из компилируемого литерала. То есть Массив литералов, который с помощью decodeAsLiteralArray реконструирует объект.

Это не общий механизм, но в основном был изобретен для хранения спецификаций пользовательского интерфейса в методе (см. UIBuilder).

Только небольшое подмножество классов поддерживает такой тип кодирования/декодирования, и я не уверен, что OrderedCollection делает это на любом диалекте. В том, что я использую (ST/X), это не так, и я получаю команду doesNotUnderstand.

Однако было бы относительно легко добавить требуемый кодировщик/декодер и сделать это возможным.

Но, как я сказал, его предполагаемое использование предназначено для UIspecs, а не как механизм постоянной стойкости (скомпилированный объект). Поэтому я не рекомендую использовать его для этого.

Смежные вопросы