2010-05-19 5 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) 

$ 코드와 구분하여 선택하고 형식이 1 인 개체를 선택하는 방법이 있습니까? LINQ를 PowerShell과 함께 사용하려면 어떻게해야합니까? 별개의 사용을 위해목록 쿼리 PowerShell의 LINQ 스타일

답변

16

키이스가 말한 바. 또한 C#에서 생성자를 변경하고 Sort cmdlet에 -Unique 매개 변수를 사용했습니다.

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

고유 매개 변수의 예와 (Select 별칭)에 Select-Object cmdlet을 : 필터링을위한

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

Where-Object cmdlet을 사용하여이 (Where? 별칭) :

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

로 LINQ의 경우 PowerShell은 LINQ에 중요한 일반 .NET 메서드 또는 정적 확장 메서드를 호출 할 수 없으므로 PowerShell에서 LINQ 연산자를 사용할 수 없습니다.

편집자 주 : 지금 지원 그 일을 PSv3 +.

1

간단한 질문, 간단한 대답 :

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

; 다른 말로하면, 귀하의 전화는 효과적인 노 - op입니다. – mklement0

0

Doug Finke's helpful answerKeith Hill's helpful answer는 당신에게 .Distinct().Where() LINQ 방법에 PowerShell을-관용적 아날로그를 보여줍니다.


PowerShell을 v3에서

이상 당신이 지금 사용 LINQ.

이 솔루션은 아래의 LINQ이 문제를 해결하기 위해 사용될 수 있다는 것을 보여줍니다뿐만 아니라 이렇게하면 다소 성가신을하고 고급 쿼리 기능 및/또는 성능이을 중요한 필요하면 노력 아마 에만 가치가 있음을 보여줍니다.

  • PowerShell을에서 LINQ를 사용하는 방법에 대한 일반적인 개요에 대한 내 this answer를 참조하십시오. 유망하지만 작성된`[pack_code]`인스턴스를 복제 인식하기 위해이 사용자 정의 비교 논리를 찾을 수 없기 때문에 코드가 작동하지 않습니다

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