Мое обходное решение:
function add(a, b, precision) {
var x = Math.pow(10, precision || 2);
return (Math.round(a * x) + Math.round(b * x)) / x;
}
precision относится к числу цифр, которые вы хотите сохранить после десятичной точки во время добавления.
Я думаю, вы могли бы использовать параметр ExpandProperty
в Select-Object
.
Например, чтобы получить список текущего каталога и просто отобразить свойство Name, следующее:
ls | select -Property Name
Это все еще возвращает объекты DirectoryInfo или FileInfo. Вы всегда можете проверить тип, проходящий через трубопровод, по трубопроводу до Get-Member (псевдоним gm
).
ls | select -Property Name | gm
Итак, чтобы развернуть объект должен быть типом свойства, которое вы ищете, вы можете сделать следующее:
ls | select -ExpandProperty Name
В вашем случае вы можете просто сделать следующее, чтобы переменная была массивом строк, где строки являются свойством Name:
$objects = ls | select -ExpandProperty Name
В дополнение к ранее имеющимся полезным ответам с указанием того, когда использовать этот подход и сравнение производительности.
$objects.Name(PSv3 +), как показано в ответе rageandqq , который синтаксически проще и намного быстрее. Доступ к свойству на уровне коллекции для получения значений членов в качестве массива называется перечислением членов и является функция PSv3 + ; В качестве альтернативы, в PSv2 используйте инструкцию
foreach
, выход которой вы также можете назначить непосредственно переменной: $results = foreach ($obj in $objects) { $obj.Name }Компромиссы: как входной массив сбора, так и выходной массив должны вписываться в память как целое . Если входная коллекция сама является результатом команды (конвейера) (например,
(Get-ChildItem).Name
), команда должна сначала выполняться до завершения до того, как к элементам результирующего массива можно получить доступ. $objects | Select-Object -ExpandProperty Name. Необходимость в
-ExpandProperty
объясняется в ответ Скотта Саада . Вы получаете обычные преимущества конвейера от обработки по одному, что, как правило, дает выход сразу и сохраняет постоянство памяти (если вы в конечном итоге не собираете результаты в памяти). Компромисс: использование трубопровода сравнительно медленно . Для коллекций ввода small (массивов) вы, вероятно, не заметите разницы и, особенно в командной строке, иногда можете ввести команду легко.
Вот простая альтернатива, которая, однако, является самым медленным ; он использует упрощенный синтаксис
$objects | Select-Object -ExpandProperty Name, называемый оператором (опять же, PSv3 +):; например, следующее решение PSv3 + легко добавляется к существующей команде:
$objects | % Name # short for: $objects | ForEach-Object -Process { $_.Name }
Для полноты: малоизвестный метод сбора данных PSv4 + .ForEach()
- еще одна альтернатива:
# By property name (string):
$objects.ForEach('Name')
# By script block (much slower):
$objects.ForEach({ $_.Name })
ForEach-Object
. Ниже приведены временные интервалы выборки для различных подходов на основе входного набора объектов 100,000
, усредненных по 100 прогонам; абсолютные цифры не важны и варьируются в зависимости от многих факторов, но это должно дать вам представление о относительном :
Command FriendlySecs (100-run avg.) Factor
------- --------------------------- ------
$objects.ForEach('Number') 0.078 1.00
$objects.Number 0.079 1.02
foreach($o in $objects) { $o.Number } 0.188 2.42
$objects | Select-Object -ExpandProperty Number 0.881 11.36
$objects.ForEach({ $_.Number }) 0.925 11.93
$objects | % { $_.Number } 1.564 20.16
$objects | % Number 2.974 38.35
foreach
работает примерно на 2,5 медленнее, чем на самом деле, но все же примерно в 4-5 раз быстрее, чем самое быстрое решение для трубопровода. .ForEach({ ... }
) резко замедляет работу, так что он практически совпадает с самым быстрым решением на основе трубопровода (Select-Object -ExpandProperty
). % Number
(ForEach-Object Number
), любопытно, выполняет худшее, хотя % Number
является концептуальным эквивалентом % { $_.Number }
). Исходный код для тестов:
Примечание. Загрузите функцию Time-Command
из этого Gist для выполнения этих тестов.
$count = 1e5 # input-object count (100,000)
$runs = 100 # number of runs to average
# Create sample input objects.
$objects = 1..$count | % { [pscustomobject] @{ Number = $_ } }
# An array of script blocks with the various approaches.
$approaches = { $objects | Select-Object -ExpandProperty Number },
{ $objects | % Number },
{ $objects | % { $_.Number } },
{ $objects.ForEach('Number') },
{ $objects.ForEach({ $_.Number }) },
{ $objects.Number },
{ foreach($o in $objects) { $o.Number } }
# Time the approaches and sort them by execution time (fastest first):
Time-Command $approaches -Count $runs | Select Command, FriendlySecs*, Factor
В качестве еще более простого решения вы можете просто использовать:
$results = $objects.Name
Который должен заполнить $results
массивом всех значений свойств «Имя» элементов в $objects
.