You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell中遍历二维数组(foreach)时的异常行为疑问

Hey Ben, let's clear up the confusion around PowerShell's jagged arrays and how foreach interacts with them—it's a common gotcha, so you're not alone here!

First, let's break down your test code to understand why you're seeing unexpected results:

$testarray = @( ("a",1),("b",2))
echo $testarray[0]
echo "____________"
foreach ($test in $testarray) {
    echo $test[0]
}

When you run echo $testarray[0], PowerShell automatically enumerates the elements of that inner array (("a",1)), so it prints a and 1 on separate lines. That's PowerShell's default behavior—unless you explicitly tell it not to, it will expand arrays when outputting them.

But in your foreach loop, $test is assigned to each top-level element of $testarray—meaning first it's ("a",1), then it's ("b",2). So when you do echo $test[0], you're asking for the first element of each inner array, which gives you a then b. That's why your loop output doesn't match the first echo—they're doing two completely different things!

Your thought about $test[0][1] is a mix-up: since $test is already the inner array, you'd use $test[1] to get the value 1 during the first loop iteration. To grab that same value directly from the original array, you'd use $testarray[0][1].

Is This Expected Behavior?

Absolutely. PowerShell treats @( ("a",1), ("b",2) ) as a jagged array (an array made of other arrays). The foreach loop iterates over the outer array's elements—each inner array—not every nested element across all arrays. The output difference comes down to how PowerShell handles array enumeration when you output an array directly vs accessing a specific element of an array in a loop.

Fixing Your Test Code

If you want the loop to output both elements of each inner array (like the first echo does), just output $test directly:

$testarray = @( ("a",1),("b",2))
echo $testarray[0]
echo "____________"
foreach ($test in $testarray) {
    echo $test  # This will print both elements of each inner array, one per line
}

Or if you want to access each element explicitly for more control:

foreach ($test in $testarray) {
    echo "First value: $($test[0])"
    echo "Second value: $($test[1])"
}

A Better Approach for Your File Object Use Case

Storing file objects and friendly names in a jagged array works, but using custom objects will make your code far more readable and less error-prone. Here's how to rewrite your file array code:

$SLFile = (Get-ChildItem -Path $folder -Filter "file1_*.csv" | Sort-Object LastWriteTime -Descending)[0]
$SOHFile = (Get-ChildItem -Path $folder -Filter "file2_*.csv" | Sort-Object LastWriteTime -Descending)[0]

# Create an array of custom objects with meaningful property names
$fileArray = @(
    [PSCustomObject]@{
        File = $SLFile
        FriendlyName = "FriendlyFile1Name"
    },
    [PSCustomObject]@{
        File = $SOHFile
        FriendlyName = "FriendlyFile2Name"
    }
)

# Accessing data is now intuitive
foreach ($entry in $fileArray) {
    Write-Host "Processing file: $($entry.File.Name) (Friendly name: $($entry.FriendlyName))"
}

This way, you don't have to remember which index corresponds to the file vs the friendly name—you just use clear, descriptive property labels.


内容的提问来源于stack exchange,提问作者user7925487

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:59:32