2011-02-09 4 views
11

Я хочу выполнить итерацию по набору определенных значений. Простой пример нижеDelphi for..in loop set enumeration order

program Project1; 
{$APPTYPE CONSOLE} 

var 
    a, b: word; 
    wait: string; 

begin 
    a := 0; 
    for b in [1,5,10,20] do 
    begin 
    a := a + 1; 
    writeln('Iteration = ', a, ', value = ', b); 
    end; 

    read(wait); 

end. 

образец кода здесь делает то, что я ожидал и производит следующее

Iteration = 1, значение = 1

итерация = 2, значение = 5

итерация = 3, значение = 10

Итерация = 4, значение = 20

Теперь, если я изменить порядок набора

for b in [20,10,5,1] do 

Выход такой же, как оригинал, то есть порядок значений не сохраняется.

Каков наилучший способ реализации этого?

ответ

16

Наборы не являются заказанными контейнерами. Вы не можете изменить порядок содержимого набора. Цикл for-in всегда выполняет итерации через множества в численном порядке.

Если вам нужен упорядоченный список номеров, вы можете использовать массив или TList<Integer>.

var 
    numbers: array of Word; 
begin 
    SetLength(numbers, 4); 
    numbers[0] := 20; 
    numbers[1] := 10; 
    numbers[2] := 5; 
    numbers[3] := 1; 
    for b in numbers do begin 
    Inc(a); 
    Writeln('Iteration = ', a, ', value = ', b); 
    end; 
end. 
+15

например. 'для b в TIntegerDynArray.Create (20,10,5,1) do' –

+0

Спасибо за ответ. Существует ли менее длинный способ создания упорядоченных значений массива? И комментарий выше отвечает на это тоже. Иногда StackOverflow слишком быстр :-) – HMcG

+0

Синтаксис динамического массива-конструктора, который демонстрирует Дэвид, новее, чем цикл for-in. Есть некоторые версии Delphi, которые могут использовать последний, но не первый, и если вы используете один из них, то вы не можете многое сделать. Вы могли бы написать свою собственную функцию, которая преобразует открытый массив в динамический массив. –

5

В математике набор не имеет особого порядка.

В pascal набор представляет собой bitmap в представлении памяти элементов, присутствующих в наборе (в пределах юниверса возможных элементов, определяемых базовым типом).

Вы не можете «изменить» порядок набора, потому что он по определению бессмыслен для него.

Как и в представлении памяти pascal, набор всегда повторяется «по порядку».

+0

спасибо за объяснение. Должен признаться, что я не понял, что это, как вы говорите, сопоставленное представление значений - это также объясняет, почему дублирующиеся значения не имеют никакого эффекта - это значение уже представлено. – HMcG

9

Вы можете объявить постоянный массив вместо константного набора.

program Project1; 
{$APPTYPE CONSOLE} 

var 
    a, b: word; 
    wait: string; 
const 
    values: array[0..3] of word = (20,5,10,1); 

begin 
    a := 0; 
    for b in values do 
    begin 
    a := a + 1; 
    writeln('Iteration = ', a, ', value = ', b); 
    end; 

    read(wait); 

end. 
+0

Еще одна приятная реализация, и эта не зависит от других единиц. Благодарю. – HMcG