Проблема строк данных в строку в массив - PullRequest
1 голос
/ 02 февраля 2020

У меня очень странная проблема. У меня есть объект, заполненный кучей строк. Я могу получить к ним хороший доступ, но мне нужно добавить "." (точка) для каждого значения внутри него, поэтому я в итоге преобразую каждую запись в строку, используя a для каждого l oop и добавляя «.» после обрезки значений. Однако теперь проблема в том, что я хотел бы назначить каждую из этих строк (а строки имеют только один столбец / элемент) другому массиву / объекту, чтобы я мог получить к ним доступ позже.

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

Пожалуйста, помогите. Вот модифицированный пример кода:

[String] $DBNms = @();

ForEach($DBName in $objDBNms){ 

   $tempText += $DBName.Item(0).ToString().Trim() + "."

   $DBNms += $tempText
}  

 Write-Host($DBNms.GetType()) #And this is showing up a string, while I want it to be an array.

И если я печатаю $ DBNms, это действительно показывает строку, соединенную вместе в одну строку, в то время как я на самом деле хочу, чтобы она была похожа на $ DBNms [0] = значение первого элемента, $ DBNms [1] = значение второго элемента и т. д.

1 Ответ

1 голос
/ 02 февраля 2020

[String] $DBNms = @(); делает $DBNms переменную с ограничением по типу , поскольку литерал типа [string] расположен влево переменной $DBNms, тип которой тогда заблокирован в в виде строки; то есть как a single string .

Вы хотели создать строку array , которая в PowerShell представлена ​​как [string[]]:

[string[]] $DBNames = @()

Преобразования типов PowerShell автоматизированы c (и очень гибкие), поэтому [String] $DBNms = @() не сообщает об ошибке , он тихо преобразует пустой массив (@()) в пустую строку (как того требует ограничение типа):

PS> [string] $DBNames = @(); '' -eq $DBNames
True

Гораздо более эффективный способ сбора значений из нескольких итераций в массиве заключается в использовании оператора foreach в качестве выражения , в этом случае PowerShell автоматически собирает выходные данные для вас:

[string[]] $DBNms = foreach ($DBName in $objDBNms){ 

   # Output this expression's value as-is.
   # PowerShell will collect the individual iterations' values for you.
   $DBName.Item(0).ToString().Trim() + "."

}  

Вышесказанное не только более кратко, чем ваш первоначальный подход, но и, что более важно, более эффективно:

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

  • Что PowerShell должен делать всякий раз, когда вы используете += с массивом, это выделять новый массив за кулисами с оригинальными элементами скопированы и добавлены новые элементы; новый массив затем автоматически присваивается переменной.


Примечание: альтернатива и следующее лучшее решение для использования всего l oop в качестве выражение должно использовать и эффективно расширяемый тип списка , в частности [System.Collections.Generic.List[object]] (System.Collections.Generic.List`1):

# Create the list.
# The 'System.' namespace prefix is optional.
[Collections.Generic.List[string]] $DBNms = @()

foreach ($DBName in $objDBNms) { 

   # Add to the list, using its .Add() method.
   # Note: Do NOT try to add with +=
   $DBNms.Add($DBName.Item(0).ToString().Trim() + ".")

}  

You ' Этот подход понадобится вам, если ваш l oop будет делать больше, чем вывод одного значения за одну итерацию, например, необходимо добавить к несколько коллекций.

Примечание. Раньше он был обычным для использования System.Collections.ArrayList экземпляров вместо; однако:

  • Использование этого типа больше не рекомендуется (см. предупреждение в связанной справке topi c); вместо этого используйте [System.Collections.Generic.List[object]], что дополнительно позволяет строго набирать коллекцию (замените [object] на интересующий тип, такой как [string] в приведенном выше коде).

  • У него есть недостаток метода .Add(), который имеет возвращаемое значение , которое необходимо явно отключить (например, $null = $lst.Add(...)), чтобы он не мог случайно загрязнить ваш код. поток вывода (выдаст неожиданный дополнительный вывод).

...