2010-05-19 25 views
9
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) 

$ kodlarından ayrı seçmek ve türün 1'e eşit olduğu nesneleri seçmek için bir yol var mı? LINQ'i PowerShell ile nasıl kullanabilirim? farklı kullanım içinSorgu listesi PowerShell'de LINQ stili

cevap

16

Keith ne dedi. Artı, C# 'daki kurucuyu değiştirdi ve Sort cmdlet'inde -Unique parametresini kullandı.

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} 
26

benzersiz parametre ile örn (Select diğer adı) Select-Object cmdlet'in: filtreleme için

PS> 1,2,3,4,4,2 | Select-Object -Unique 
1 
2 
3 
4 

Where-Object cmdlet'ini kullanımı (Where ve ? diğer adı):

PS> $codes | where {$_.Type -eq '1'} 

zamanda LINQ için, PowerShell, LINQ için çok önemli olan genel .NET yöntemlerini veya statik uzantı yöntemlerini çağırmayı desteklemediğinden, PowerShell'de LINQ operatörlerini kullanamazsınız.

Editörün notu: Şimdi destek böyle şeyler yapar PSv3 +.

1

basit bir soru, basit cevap:

[Linq.Enumerable]::Distinct($codes) 
+0

; başka bir deyişle: aramanız etkili bir no-op. – mklement0

0

Doug Finke's helpful answer ve Keith Hill's helpful answer size .Distinct() ve .Where() LINQ yöntemlerine PowerShell-deyimsel analoglarını göstermektedir.


PowerShell v3 olarak

veya daha yüksek şimdi can kullanım LINQ.

çözümü aşağıda LINQ sorunu çözmek için kullanılabileceğini göstermektedir, aynı zamanda bunu yaparken biraz hantal olduğunu ve gelişmiş sorgulama özellikleri ve/veya performans konularda gerekirse çaba muhtemelen sadece değer olduğunu göstermektedir.

  • PowerShell LINQ nasıl kullanılacağına dair genel bir bakış için madenin this answer bakınız. umut verici, ama yazıldığı gibi `[pack_code]` örneklerini çoğaltmak tanımak amacıyla bu özel karşılaştırma mantığı eksik olduğundan kodunuzu çalışmaz

# 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' } 
)