在PowerShell中查询列表LINQ样式
是否有一种方法可以从$CODE中选择distinct并选择类型为1的对象?如何将LINQ与PowerShell一起使用?对于distinct,请使用别名为Select的Select Object cmdlet,以使用唯一参数进行选择,例如:在PowerShell中查询列表LINQ样式,linq,powershell,Linq,Powershell,是否有一种方法可以从$CODE中选择distinct并选择类型为1的对象?如何将LINQ与PowerShell一起使用?对于distinct,请使用别名为Select的Select Object cmdlet,以使用唯一参数进行选择,例如: add-type -Language CSharpVersion3 -TypeDefinition @" public class pack_code { public pack_code() {} publ
add-type -Language CSharpVersion3 -TypeDefinition @"
public class pack_code
{
public pack_code() {}
public string code { get; set; }
public string type { get; set; }
}
"@
$a = New-Object pack_code
$a.code = "3"
$a.type = "5"
$b = New-Object pack_code
$b.code = "2"
$b.type = "5"
$c = New-Object pack_code
$c.code = "2"
$c.type = "5"
$d = New-Object pack_code
$d.code = "1"
$d.type = "1"
$codes = New-Object 'System.Collections.Generic.List[object]'
$codes.add($a)
$codes.add($b)
$codes.add($c)
$codes.add($d)
要进行筛选,请使用别名为Where和?的Where-Object cmdlet:
至于LINQ,您不能在PowerShell中使用LINQ运算符,因为PowerShell不支持调用通用.NET方法或静态扩展方法,这两种方法对LINQ都至关重要
编者按:PSv3+现在确实支持这些东西。基思说的。另外,更改了C中的构造函数,并在Sort cmdlet上使用了-Unique参数
PS> $codes | where {$_.Type -eq '1'}
简单的问题,简单的回答:
Add-Type -Language CSharpVersion3 -TypeDefinition @"
public class pack_code
{
public pack_code(string code, string type) {
this.code=code;
this.type=type;
}
public string code { get; set; }
public string type { get; set; }
}
"@
$codes = New-Object 'System.Collections.Generic.List[object]'
$codes.Add( ( New-Object pack_code 3, 5 ))
$codes.Add( ( New-Object pack_code 2, 5 ))
$codes.Add( ( New-Object pack_code 2, 5 ))
$codes.Add( ( New-Object pack_code 1, 1 ))
$codes.Add( ( New-Object pack_code 2, 2 ))
$codes.Add( ( New-Object pack_code 2, 1 ))
$codes.Add( ( New-Object pack_code 2, 1 ))
$codes | sort code, type -Unique | where {$_.type -eq 1}
并向您展示PowerShell与.Distinct和.Where LINQ方法的惯用类比
在PowerShell v3或更高版本中,您现在可以使用LINQ
下面的解决方案演示了LINQ可以用来解决您的问题,但也表明这样做有点麻烦,并且可能只在您需要高级查询功能和/或性能问题时才值得付出努力
有关如何使用PowerShell中的LINQ的一般概述,请参见我的。
这是有希望的,但正如编写的代码那样,您的代码将无法工作,因为它缺少用于识别重复[pack_code]实例的自定义比较逻辑;换句话说:你的电话是有效的禁止操作。
Add-Type -Language CSharpVersion3 -TypeDefinition @"
public class pack_code
{
public pack_code(string code, string type) {
this.code=code;
this.type=type;
}
public string code { get; set; }
public string type { get; set; }
}
"@
$codes = New-Object 'System.Collections.Generic.List[object]'
$codes.Add( ( New-Object pack_code 3, 5 ))
$codes.Add( ( New-Object pack_code 2, 5 ))
$codes.Add( ( New-Object pack_code 2, 5 ))
$codes.Add( ( New-Object pack_code 1, 1 ))
$codes.Add( ( New-Object pack_code 2, 2 ))
$codes.Add( ( New-Object pack_code 2, 1 ))
$codes.Add( ( New-Object pack_code 2, 1 ))
$codes | sort code, type -Unique | where {$_.type -eq 1}
[Linq.Enumerable]::Distinct($codes)
# Create the type whose instances will make up the list to filter.
# Make it implement IEquatable<T> with custom comparison logic that
# compares property values so that the .Distinct() LINQ method works correctly.
Add-Type -TypeDefinition @"
public class pack_code : System.IEquatable<pack_code>
{
public string code { get; set; }
public string type { get; set; }
// IEquatable<T> interface implementation
// Test equality of this object with another of the same type.
public bool Equals(pack_code other) {
// Note: Normally, you'd need to deal with the case of other == null as well.
return this.code == other.code && this.type == other.type;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode() {
return this.code.Length + this.type.Length;
}
}
"@
# Create the list to filter.
# Note:
# * Despite not having a constructor for [pack_code], PowerShell is smart
# enough to construct an instance from a cast from a hashtable that contains
# entries whose names match the settable [pack_code] properties.
# * The array of [pack_code] instances is then cast to the list type.
# * The list contains 3 objects of type 1, but only 2 distinct ones.
$codes = [System.Collections.Generic.List[pack_code]] (
[pack_code] @{code = '2'; type = '1'},
[pack_code] @{code = '3'; type = '5'},
[pack_code] @{code = '2'; type = '1'},
[pack_code] @{code = '1'; type = '1'}
)
# Invoke the LINQ methods as static methods of the
# [System.Linq.Enumerable] type to
# return all distinct objects whose type property is ‘1’.
# Note that the result will be an *iterator*; if you want a
# static array, wrap the call in [Linq.Enumerable]::ToArray(...)
[Linq.Enumerable]::Where(
[Linq.Enumerable]::Distinct($codes),
[Func[pack_code, bool]] { $Args[0].type -eq '1' }
)