首页 > 解决方案 > Powershell - 分别打印列表长度

问题描述

我想在 Powershell 中写两件事。例如; 我们有一个清单:

$a=@('ab','bc','cd','dc')

我想写:

1 >> ab
2 >> bc
3 >> cd
4 >> dc

我希望这是基于列表长度的动态。

感谢您的帮助。

标签: arrayslistpowershellindexing

解决方案


使用for循环,以便您可以跟踪索引:

for( $i = 0; $i -lt $a.Count; $i++ ){
  "$($i + 1) >> $($a[$i])"
}

解释这是如何工作的:

  • 循环由for三个部分定义,由分号分隔;

    • 第一部分声明变量,在这种情况下我们定义$i = 0. 这将是我们的索引参考。
    • 第二部分是循环继续的条件。只要$i小于 $a.Count循环就会继续。我们不想超出列表的长度,否则您会遇到不良行为。
    • 第三部分是循环的每次迭代结束时发生的事情。在这种情况下,我们希望$i每次将计数器增加 1($i++是“递增$i1”的简写)
    • 这种表示法的细微差别比我所包含的要多,但它与循环的工作方式无关。您可以在此处阅读有关一元运算符的更多信息。
  • 对于循环体本身,我将解释字符串

    • 返回一个对象而不分配给一个变量,例如这个字符串,实际上与使用相同Write-Output
      • 在大多数情况下,Write-Output实际上是可选的(通常不是您想要在屏幕上显示文本的内容)。我在这里的回答更详细地介绍了不同的Write-cmdlet、输出流和重定向。
    • $()子表达式运算符,用于返回表达式以在父表达式中使用。在这种情况下,我们返回$i + 1插入最终字符串的结果。
      • 它的独特之处在于它可以直接在字符串中使用,这与相似但不同的数组子表达式运算符分组运算符不同。
      • 如果没有子表达式运算符,您会得到类似的东西,0 + 1因为它会插入值,$i但会呈现 + 1字面意思。
    • 之后,>>我们使用另一个子表达式将$i第 th索引的值插入$a到字符串中。
      • 虽然简单的变量扩展会将.ToString()数组的值插入$a到最终字符串中,但引用数组的索引必须在子表达式中完成,否则[]将按字面意思呈现。

在循环中使用foreachand的解决方案确实有效,但是 while可以获取当前索引,通过迭代数组直到找到匹配的对象引用,然后返回索引。对于大型数组,每次迭代将花费越来越长的时间。for 循环没有这个限制。$a.IndexOf($number)$a.IndexOf($number).IndexOf(object)

考虑以下具有更大数组的示例:

# Array of numbers 1 through 65535
$a = 1..65535

# Use the for loop to output "Iteration INDEXVALUE"
# Runs in 106 ms on my system
Measure-Command { for( $i = 0; $i -lt $a.Count; $i++ ) { "Iteration $($a[$i])" } }

# Use a foreach loop to do the same but obtain the index with .IndexOf(object)
# Runs in 6720 ms on my system
Measure-Command { foreach( $i in $a ){ "Iteration $($a.IndexOf($i))" } }

另一件需要注意的事情是,虽然您可以更改集合元素的属性System.Concurrent.Collections和执行方法,但在使用其枚举器时,您不能更改非集合集合(不在命名空间中的任何集合)的元素值。虽然不可见,但foreach(并且相关地ForEach-Object)隐式调用集合的.GetEnumerator()循环方法。这不会像其他 .NET 语言那样引发错误,但 IMO 应该如此。它似乎会接受集合的新值,但一旦退出循环,该值将保持不变。

这并不是说永远不应该使用循环或者你做了任何“错误”的事情,但我觉得在发现自己处于适合更好构造的情况foreach之前应该知道这些细微差别。


推荐阅读