Запрос списка в стиле LINQ в PowerShell - PullRequest
10 голосов
/ 20 мая 2010
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?

Ответы [ 4 ]

26 голосов
/ 20 мая 2010

Для отдельного использования используйте командлет Select-Object (с псевдонимом Select) с параметром Unique, например ::

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

Для фильтрации используйте командлет Where-Object (с псевдонимом Where и ?):

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

Что касается LINQ, вы не можете использовать операторы LINQ в PowerShell, потому что PowerShell не поддерживает вызов универсальных методов .NET или статических методов расширения, которые имеют решающее значение для LINQ.

Примечание редактора: PSv3 + сейчас поддерживает поддержку этих вещей.

17 голосов
/ 20 мая 2010

Что сказал Кит. Кроме того, изменил конструктор в своем C # и использовал параметр -Unique в командлете Sort.

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}
1 голос
/ 16 ноября 2016

простой вопрос, простой ответ:

[Linq.Enumerable]::Distinct($codes)
0 голосов
/ 07 января 2018

Полезный ответ Дуга Финка и Полезный ответ Кейта Хилла покажет вам PowerShell-идиоматические аналоги .Distinct() и .Where() LINQ-методов.


В PowerShell v3 или выше Вы сейчас можете использовать LINQ .

Приведенное ниже решение демонстрирует, что LINQ можно использовать для решения вашей проблемы, но также показывает, что это несколько громоздко и, вероятно, стоит только усилий, если вам нужны расширенные функции запросов и / или производительность имеет значение .

  • См. мой ответ мой общий обзор того, как использовать LINQ из PowerShell.

# 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' }
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...