Преобразование в массив

При запуске конвейера PowerShell этот конвейер может вернуть 0, 1 или несколько элементов. Если вы присваиваете результат конвейера переменной, вы получите $null, один элемент или массив элементов, соответственно. Часще всего вы не обращаете внимание на то какие типы возвращаются, но иногда вы предпочли бы принудительно приводить результат, чтобы он всегда представлял собой массив. В этих случаях вы можете использовать @( ... ). Например:

 $a = @(get-childitem)

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

Это обычно работает достаточно хорошо, но я обнаружил, что я обычно решаю, что мне нужен массив, уже глубоко закопавшись в написание конвейера. После этого мне приходится сдвигать курсор к началу конвейера, чтобы вставить «@(». Несколько раз повторив эту операцию, я устал и решил, что лучше буду добавлять в конец конвейера что-нибудь, что преобразует результаты в массив. Так родилась моя функция ToArray.

 

 
function ToArray
{
  begin
  {
    $output = @(); 
  }
  process
  {
    $output += $_; 
  }
  end
  {
    return ,$output; 
  }
}

Достаточно просто, да? Начальный блок создает новый пустой массив. Блок обработки, который вызывается для каждого элемента конвейера, добавляет элемент к массиву, а конечный блок просто помещает этот массив в массив длиной 1 и записывает его в конвейер. Мне приходится помещать массив $output в массив из 1-го элемента, поскольку конвейер раскрывает все перечисления (ну ладно, почти все). Этот способ просто раскрывает массив из 1-го элемента и находит, что осталось в моем исходном массиве.

Вы должны знать, что это не самый производительный способ. Для каждого элемента я создаю новый массив. Если я помещаю в конвейер множество элементов, мне веросятно было бы лучше использовать ArrayList, в конце преобразуя его в массив. Я оставляю это вам в качестве упражнения.

Для меня это срабатывает. Это несложно и упрощает мне жизнь. Теперь если мне нужно создать массив результатов, я просто передаю их в ToArray. Мне больше не нужно возвращаться в начало конвейера. :-)

 

 $a = get-childitem | ToArray

- Марсель Ортиц Сото (Marcel Ortiz Soto) [MSFT]

P.S. Если вам кажется, что ToArray – это слишком длинно, создайте сокращение.

Перевод: Виктор Горбунков