Powershell $this 变量在数组索引中不起作用
Powershell $this variable does not work inside array indexing
我正在尝试在 Powershell 中模拟 MATLAB 的“end
”索引关键字(例如 A[5:end]
),但我不想键入数组名称(例如 $array
) 为
访问 $array.length
$array[0..($array.length - 2)]
如另一个 Stackflow question 中所述。我试过 $this
(0..7)[4..($this.Length-1)]
给出的 ($this.Length-1)
似乎被解释为 -1,如输出所示
4
3
2
1
0
7
这让我觉得 $this 在 []
中用于索引数组时是空的。有没有一种方法可以让数组在不显式重复变量名的情况下引用自身,这样我就可以调用数组的方法来派生索引?这对于在利用方法链(如 a.b.c.d[4..end]
)的同时模拟逻辑索引非常方便。
PowerShell 没有任何引用“此索引访问运算符所针对的集合”的工具,但如果您想跳过 collection/enumerable 的前 N 项,您可以使用 Select -Skip
:
0..7 |Select -Skip 4
补充:
automatic $this
variable 在索引表达式 ([...]
) 中不可用 ,仅在自定义 class
es (以指代手头的实例)并在脚本块中充当 .NET 事件委托(以指代事件发送者)。
但是,对于您想要实现的目标,您不需要引用输入数组(集合)作为一个整体:相反, 一个 抽象符号 用于引用相对于输入数组的 end 的索引应该足够 ,并且理想情况下也适用于“所有剩余元素”逻辑。
您可以使用负索引来引用相对于输入数组末尾的索引[=139] =],但 仅适用于 个人 索引 :
# OK: individual negative indices; get the last and the 3rd last item:
('a', 'b', 'c', 'd')[-3, -1] # -> 'b', 'd'
不幸的是,因为索引表达式中的 ..
指的是独立的 general-purpose range operator,所以 而不是 当负索引用作 范围端点时 range-based 数组切片 工作 :
# !! DOES NOT WORK:
# *Flawed* attempt to get all elements up to and including the 2nd last,
# i.e. to get all elements but the last.
# 0..-2 evaluates to array 0, -1, -2, whose elements then serve as the indices.
('a', 'b', 'c', 'd')[0..-2] # -> !! 'a', 'd', 'c'
也就是说,一般范围操作 0..-2
的计算结果为数组 0
、-1
、-2
,结果索引用于提取元素。
正是这种行为目前需要对 everything-except-the-last-N-elements 逻辑 的索引表达式中的数组进行不方便的显式引用,例如 $array[0..($array.length - 2)]
在你的问题中提取除最后一个元素之外的所有元素。
GitHub issue #7940 proposes introducing new syntax that addresses this problem, by effectively implementing C#-style ranges:
虽然没有就语法达成一致,也没有承诺实施此增强功能,但可以选择直接借用 C# 的语法:
Now
Potential future syntax
Comment
$arr[1..($arr.Length-2)]
$arr[1..^1
]
From the 2nd el. through to the next to last.
$arr[1..($arr.Length-1)]
$arr[1..
]
Everything from the 2nd el.
$arr[0..9]
$arr[..9]
Everything up to the 10th el.
$arr[-9..-1]
$arr[^9..]
Everything from the 9th to last el.
注意 from-the-end、1
索引语法的逻辑(例如,^1
指的是 last 元素)当作为范围端点:是up-to-but-排除逻辑,所以..^1
表示:到索引在最后一个之前,即倒数第秒。
至于解决方法:
将Select-Object
与-Skip
/-SkipLast
一起使用在简单情况下很方便,但是:
- 与索引表达式 (
[...]
) 相比表现不佳(见下文)
- 缺乏后者的灵活性[1]
- 一个值得注意的限制是您不能在单个
Select-Object
调用中同时使用 -Skip
和 -SkipLast
; GitHub issue #11752 建议取消此限制。
例如,在下面的示例中(它补充了 Mathias 的 -Skip
示例),它提取了除最后一个元素之外的所有元素:
# Get all elements but the last.
$arr | Select-Object -SkipLast 1
数组$arr
是枚举,即它的元素通过管道一个一个发送,一个称为 streaming.
的过程
捕获时,流元素被收集在常规的 [object[]]
类型的 PowerShell 数组中,即使输入数组是强类型的 - 然而,这种严格类型的损失也适用通过 [...]
.
提取多个元素
根据数组的大小和所需的切片操作数,性能差异可能很大。
[1] 值得注意的是,您可以在 [...]
中使用 任意表达式 ,这在 中有更详细的讨论。
我正在尝试在 Powershell 中模拟 MATLAB 的“end
”索引关键字(例如 A[5:end]
),但我不想键入数组名称(例如 $array
) 为
$array.length
$array[0..($array.length - 2)]
如另一个 Stackflow question 中所述。我试过 $this
(0..7)[4..($this.Length-1)]
给出的 ($this.Length-1)
似乎被解释为 -1,如输出所示
4
3
2
1
0
7
这让我觉得 $this 在 []
中用于索引数组时是空的。有没有一种方法可以让数组在不显式重复变量名的情况下引用自身,这样我就可以调用数组的方法来派生索引?这对于在利用方法链(如 a.b.c.d[4..end]
)的同时模拟逻辑索引非常方便。
PowerShell 没有任何引用“此索引访问运算符所针对的集合”的工具,但如果您想跳过 collection/enumerable 的前 N 项,您可以使用 Select -Skip
:
0..7 |Select -Skip 4
补充
automatic
$this
variable 在索引表达式 ([...]
) 中不可用 ,仅在自定义class
es (以指代手头的实例)并在脚本块中充当 .NET 事件委托(以指代事件发送者)。但是,对于您想要实现的目标,您不需要引用输入数组(集合)作为一个整体:相反, 一个 抽象符号 用于引用相对于输入数组的 end 的索引应该足够 ,并且理想情况下也适用于“所有剩余元素”逻辑。
您可以使用负索引来引用相对于输入数组末尾的索引[=139] =],但 仅适用于 个人 索引 :
# OK: individual negative indices; get the last and the 3rd last item:
('a', 'b', 'c', 'd')[-3, -1] # -> 'b', 'd'
不幸的是,因为索引表达式中的 ..
指的是独立的 general-purpose range operator,所以 而不是 当负索引用作 范围端点时 range-based 数组切片 工作 :
# !! DOES NOT WORK:
# *Flawed* attempt to get all elements up to and including the 2nd last,
# i.e. to get all elements but the last.
# 0..-2 evaluates to array 0, -1, -2, whose elements then serve as the indices.
('a', 'b', 'c', 'd')[0..-2] # -> !! 'a', 'd', 'c'
也就是说,一般范围操作 0..-2
的计算结果为数组 0
、-1
、-2
,结果索引用于提取元素。
正是这种行为目前需要对 everything-except-the-last-N-elements 逻辑 的索引表达式中的数组进行不方便的显式引用,例如 $array[0..($array.length - 2)]
在你的问题中提取除最后一个元素之外的所有元素。
GitHub issue #7940 proposes introducing new syntax that addresses this problem, by effectively implementing C#-style ranges:
虽然没有就语法达成一致,也没有承诺实施此增强功能,但可以选择直接借用 C# 的语法:
Now | Potential future syntax | Comment |
---|---|---|
$arr[1..($arr.Length-2)] |
$arr[1..^1 ] |
From the 2nd el. through to the next to last. |
$arr[1..($arr.Length-1)] |
$arr[1.. ] |
Everything from the 2nd el. |
$arr[0..9] |
$arr[..9] |
Everything up to the 10th el. |
$arr[-9..-1] |
$arr[^9..] |
Everything from the 9th to last el. |
注意 from-the-end、1
索引语法的逻辑(例如,^1
指的是 last 元素)当作为范围端点:是up-to-but-排除逻辑,所以..^1
表示:到索引在最后一个之前,即倒数第秒。
至于解决方法:
将Select-Object
与-Skip
/-SkipLast
一起使用在简单情况下很方便,但是:
- 与索引表达式 (
[...]
) 相比表现不佳(见下文) - 缺乏后者的灵活性[1]
- 一个值得注意的限制是您不能在单个
Select-Object
调用中同时使用-Skip
和-SkipLast
; GitHub issue #11752 建议取消此限制。
- 一个值得注意的限制是您不能在单个
例如,在下面的示例中(它补充了 Mathias 的 -Skip
示例),它提取了除最后一个元素之外的所有元素:
# Get all elements but the last.
$arr | Select-Object -SkipLast 1
数组
的过程$arr
是枚举,即它的元素通过管道一个一个发送,一个称为 streaming.捕获时,流元素被收集在常规的
提取多个元素[object[]]
类型的 PowerShell 数组中,即使输入数组是强类型的 - 然而,这种严格类型的损失也适用通过[...]
.
根据数组的大小和所需的切片操作数,性能差异可能很大。
[1] 值得注意的是,您可以在 [...]
中使用 任意表达式 ,这在