Варианты использования [ordered], новой функции PowerShell 3.0

PowerShell 3.0 CTP1 представляет новую функцию [ordered], которая в некотором роде является сокращением для OrderedDictionary. Я не могу представить его практическое применение. Почему эта функция действительно полезна? Может ли кто-нибудь привести несколько полезных примеров?

Пример: это, ИМХО, скорее демонстрационный случай, чем практический:

$a = [ordered]@{a=1;b=2;d=3;c=4}

(Я не против, если он еще пригодится, тогда я просто ищу другие полезные случаи).

Я не ищу варианты использования OrderedDictionary, это действительно полезно. Но мы можем использовать его прямо в версии 2.0 (и я часто это делаю). Я пытаюсь понять, зачем эта новая функция [ordered] нужна дополнительно.


Собраны варианты использования из ответов:

$hash = [ordered]@{}

короче, чем

$hash = New-Object System.Collections.Specialized.OrderedDictionary

Н.Б. ordered не является настоящим сокращением для типа. New-Object ordered не работает.

Н.Б. 2: Но это все еще хороший ярлык, потому что (я думаю, не могу попробовать) он создает типичный для PowerShell словарь без учета регистра. Эквивалентная команда в версии 2.0 действительно слишком длинная:

New-Object System.Collections.Specialized.OrderedDictionary]([System.StringComparer]::OrdinalIgnoreCase)

person Roman Kuzmin    schedule 18.10.2011    source источник
comment
На самом деле это $hash = New-Object System.Collections.Specialized.OrderedDictionary   -  person manojlds    schedule 18.10.2011
comment
Спасибо, исправлено. Так что да, это экономит время на набор текста. Но это все?   -  person Roman Kuzmin    schedule 18.10.2011
comment
Но как насчет [xml], [datetime], [hashtable] и многих других, включая [int], ведь они называются ускорителями.   -  person manojlds    schedule 18.10.2011
comment
Да, но этот ускоритель отличается от упомянутого. Это не ярлык для типа. Но он использует тот же синтаксис. Это смущает. И пока единственный реальный вариант использования, когда он ускоряется, — это [ordered]@{} с пустой хеш-таблицей (я не считаю пример с жестко заданными значениями действительно полезным). Я бы не стал добавлять фичу только для этого. Я должен упустить что-то еще полезное, поэтому я задал вопрос.   -  person Roman Kuzmin    schedule 18.10.2011
comment
Может быть, дождаться финальной версии? В конце концов, теперь это CTP.   -  person manojlds    schedule 18.10.2011
comment
Ordered с жестко заданными значениями было бы полезно это решено. Но до тех пор [ordered]@{} (с пустыми хэшами) кажется единственным полезным случаем. Этот ответ принят.   -  person Roman Kuzmin    schedule 18.10.2011
comment
Поиграв с [ordered], я, наконец, нашел его очень полезным. Еще одним вариантом использования является, скажем, PSON (JSON-подобные данные в PowerShell). Мне не нравится, хотя этот многословный и запутанный (как мы видели) синтаксис [ordered]@{...}.   -  person Roman Kuzmin    schedule 11.05.2012
comment
Стоит также отметить, что это особый случай для PowerShell, как и [PSCustomObject]@{}. Это не просто кастинг из Hashtable (что в любом случае не сработает, потому что Hashtable уже потерял бы порядок). Вы можете доказать это, попробовав использовать @{} и [Ordered] в отдельных заданиях.   -  person Josh    schedule 02.10.2012


Ответы (4)


Сначала я начну с вопроса - Почему их нет?

Я могу придумать вариант использования в моем проекте, где мы используем сценарии Powershell для сборки и развертывания и yml для конфигурации (используя https://github.com/scottmuc/PowerYaml )

Конфиг из yml читается как хеш-таблицы. Задачи указаны в yml, такие как развертывание в базе данных, развертывание в iis, развертывание службы и так далее. Я хотел бы выполнить развертывание базы данных, а затем развертывание веб-сайта, чтобы впоследствии избежать iisreset. В настоящее время я должен явно смотреть на это. Теперь я могу иметь упорядоченную хэш-таблицу и сначала указать базу данных развертывания, и, следовательно, это произойдет в первую очередь.

Фрагмент:

function Convert-YamlMappingNodeToHash($node)
{
    $hash = @{}
    $yamlNodes = $node.Children

    foreach($key in $yamlNodes.Keys)
    {
        $hash[$key.Value] = Explode-Node $yamlNodes[$key]
    }
    return $hash
}

Теперь $hash =@{} становится $hash=[ordered]@{}

Я не знаю, как это означает для раздутого продукта. OrderedDictionary есть в .NET (у меня много вариантов его использования в программировании), и они только что добавили для него ускоритель.

person manojlds    schedule 18.10.2011
comment
Почему бы их не иметь?... Если это единственная причина, то это путь к раздутому продукту, возможно. - person Roman Kuzmin; 18.10.2011
comment
Записан 1 вариант использования ([ordered]@{} vs. New-Object System.Collections.OrderedDictionary). Примечание: я хотел бы иметь ускоритель [список] для ArrayList таким же образом. На самом деле я использую ArrayList чаще, чем OrderedDictionary. Возможно, это только я, конечно. - person Roman Kuzmin; 18.10.2011
comment
Итак, вы задавали вопрос с той точки зрения, что, когда есть New-Object System.Collections.OrderedDictionary, почему заказали сейчас? - person manojlds; 18.10.2011
comment
это действительно ярлык? У меня еще нет версии 3.0, чтобы попробовать. Это работает: New-Object ordered? - person Roman Kuzmin; 18.10.2011
comment
когда есть New-Object System.Collections.OrderedDictionary, почему заказали сейчас? - да, это одна из причин. - person Roman Kuzmin; 18.10.2011
comment
Нет, выдаются ошибки - New-Object : Cannot find type [ordered]: убедитесь, что сборка, содержащая этот тип, загружена. Странно... учитывая, как работают такие вещи, как хеш-таблица новых объектов и т. д. - person manojlds; 18.10.2011

На самом деле это особенно полезно для создания объектов «на лету», вроде того, как вы использовали бы ExpandoObject в C# или динамические объекты в JavaScript. Проблема с этим в предыдущих версиях PowerShell заключается в том, что @{} (который становится обычным HashTable) теряет ваш порядок ключей, поэтому отображать их на экране очень сложно.

Учти это.

foreach ($row in import-csv blah.csv) {

  # In v3: $obj = [Ordered]@{

  $obj = @{
    Name      = $row.Name
    Exists    = Test-Path $row.FileName
    OtherProp = 123
    Blah      = "derp"
    Timestamp = Get-Date
  }

  New-Object PSObject -Property $Obj

}

В PowerShell v2 порядок столбцов непредсказуем, поскольку Hashtable не сохраняет порядок ключей. В PowerShell v3, если вы использовали тип [Ordered], порядок ключей сохраняется, что делает быстрый и грязный синтаксис PowerShell почти таким же удобным, как JSON, для быстрого создания структур объектов без всех накладных расходов и проблем с производительностью, связанных с Add-Member или Select-Object.

Не случайно в PowerShell v3 появилось еще одно дополнение. Как и в случае с [Ordered], вместо этого вы можете указать [PSCustomObject]. Это создаст фактический PSObject с самого начала вместо того, чтобы требовать отдельного вызова New-Object. Я не могу сказать наверняка, но я почти уверен, что [Ordered] был побочным эффектом изменений, которые они внесли в синтаксический анализатор, чтобы это произошло. Если бы они просто выполняли преобразование из обычного Hashtable, не было бы возможности восстановить первоначальный порядок ключей.

person Josh    schedule 01.05.2012
comment
этот последний бит, использующий [PSCustomObject] для создания литералов объектов, является золотым. Намного лучше, чем New-Object psobject -Prop. Вы должны добавить пример кода, чтобы люди не пропустили его. Хотя я думаю, что это не ответ на вопрос. - person Nacht; 03.08.2016

Это полезно для выполнения SQL-соединения (также известного как слияние или архивирование) двух файлов данных. Возможно, это файлы CSV или JSON.

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

С помощью [ordered] вы можете сохранить тот же порядок, что и в исходном файле, но при этом использовать его как хеш-таблицу.

person yzorg    schedule 19.10.2013

Я видел, как он используется в сценариях powershell, которые создают вкладки с информацией и сортируют вкладки. Например, получение информации о жестком диске с нескольких серверов, каждый сервер на своей вкладке, а затем сортировка вкладок по имени сервера перед сохранением. Код «сортировки табуляцией» выглядит так:

$i=0;$wb.Worksheets | %{$i++;[ordered]@{$_.name=$i}}

-Джилл

person Gill    schedule 02.12.2013