PowerShell цикл через Арри в Арри

2

Я пытаюсь написать сценарий PowerShell для создания папки, а затем создавать файлы внутри этой папки.

$arr = @(
            ("First Folder",@("1", "2")),
            ("Sceond Folderr", @("1","2"))
        )

for ($i=0; $i -lt $arr.length; $i++)
{
    #New-Item -Path $arr[$i] -ItemType directory
    for ($a=0; $a -lt $arr[$i].length; $a++)
    {
        $file=$arr[$a]
        #New-Item -Path "$file.txt" -ItemType File
        $file
    }
}

Это результат, который я получаю.

First Folder
1
2
First Folder
1
2
Second Folder
1
2
Second Folder
1
2
Maj
источник

Ответы:

2

$arrПеременная определена как зазубренный массив :

Зубчатые массивы против многомерных массивов:

Оба полезны для хранения списков списков или массивов массивов.

  • Jagged быстрее и использует меньше памяти, чем многомерный, потому что он содержит только необходимое количество элементов.
  • Не зубчатый массив больше похож на матрицу, где каждый массив должен быть одинакового размера.

Следующий фрагмент кода показывает правильный способ обработки конкретного неровного массива $arr:

$arr = @(
            ("First Folder",@("1", "2")),
            ("Sceond Folderr", @("11","12"))
        )

for ($i=0; $i -lt $arr.length; $i++)
{
    $dire = $arr[$i][0]
    #New-Item -Path $dire -ItemType directory
    for ($a=0; $a -lt $arr[$i].length; $a++)
    {
        $file=$arr[$i][1][$a]
        #New-Item -Path "$dire`\$file`.txt" -ItemType File
        "$dire`\$file`.txt"
    }
}

Выход :

PS D:\PShell> D:\PShell\SU\1285156.ps1
First Folder\1.txt
First Folder\2.txt
Sceond Folderr\11.txt
Sceond Folderr\12.txt

PS D:\PShell> 
JosefZ
источник
Это именно то, что я искал. Я мог понять, почему папка все еще показывалась во втором цикле
май
1

Хотя StackOverflow было бы лучшим местом для публикации этого сообщения, если вы работаете с PowerShell, нет реальной необходимости использовать классические циклы for.

$arr = @(
            ("First Folder",@("1", "2")),
            ("Second Folder", @("1","2"))
        )

$arr | %{
    $folder = $_

    Write-Output $folder[0]

    $folder[1] | %{
        Write-Output "SubItem:", $_
    }
}

Это %ярлык ForEach-Object. Что касается вашего решения, используйте более описательные имена переменных, чтобы их было легче понять (для себя).

$arr = @(
            ("First Folder",@("1", "2")),
            ("Sceond Folderr", @("1","2"))
        )

# ForEach item from 0 to 1
for ($i=0; $i -lt $arr.length; $i++)
{
    # ForEach item from 0 to $arr[$i].length
    # 0, 0 - 1, 0, 0 -1 
    for ($folderKey=0; $folderKey -lt $arr[$i].length; $folderKey++)
    {
        Write-Output "Value for `$i is $i and value for `$folderKey is $folderKey"

        # Always prints just what's on the index of $i
        $file=$arr[$i]
        $file

        # The fix would be $arr[$i][$folderKey]
    }
}
Сет
источник
Приведенный выше массив был только примером. у меня будет массив 1 с папкой 100, а затем массив 2 будет иметь имя 100 файлов.
майор
я пробую это # ​​Исправление было бы $ arr [$ i] [$ folderKey], но оно все еще показывало имя папки, во 2-м цикле я не хотел бы получать имя папки, потому что я не хочу создавать файл с именем папки. это нормально
май
Если вы измените строку 16, вы получите то, что ожидаете. Очевидно, вам придется изменить код в соответствии с вашими потребностями. Это просто чтобы указать на ошибку, которую вы получили в своем исходном коде. Приведенный выше код в настоящее время выводит только имя папки.
Сет