2011-12-22 36 views
31

Tôi có một mảng các đối tượng có cấu trúc sau:Liên minh và giao lộ trong PowerShell?

structure Disk 
{ 
    int UID; 
    String Computer; 
} 

Một máy tính có thể có một loạt các đĩa được chia sẻ, và một đĩa có thể được chia sẻ giữa các máy tính.

Tôi muốn tìm hiểu tất cả các ổ đĩa chung cho tất cả các máy tính. Ví dụ, tôi có máy tính A, B và C; Đĩa 1, 2 và 3. Mảng đĩa là {1, A}, {1, B}, {2, A}, {2, B}, {2, C}, {3, A}. Kết quả mà tôi muốn là đĩa 2, bởi vì nó xuất hiện trên A, B và C.

Có cách nào hiệu quả để đạt được điều này không?

Với nhiều vòng lặp foreach nó có thể đạt được, nhưng chắc chắn tôi muốn có một cách tốt hơn. Tôi đang suy nghĩ về các hoạt động như giao lộ, nhưng không tìm thấy điều này trong PowerShell.

+1

Tôi khuyên bạn nên thay đổi tiêu đề thành "Liên minh, Giao lộ và khác biệt/Đặt phép trừ trong PowerShell". Vì vậy, chúng tôi sẽ có tất cả các hoạt động được đặt ở một nơi. –

+0

Dựa trên câu hỏi và gợi ý ở đây, tôi đã tạo ra một chức năng PowerShell để làm Liên minh, Giao lộ và Trừ cho các đối tượng. Kiểm tra xem nó ra: https://sqljana.wordpress.com/2015/09/23/perform-set-operations-union-intersection-minus-complement-using-powershell/ –

Trả lời

56

Giả sử $arr được mảng, bạn có thể làm như thế này:

$computers = $arr | select -expand computer -unique 
$arr | group uid | ?{$_.count -eq $computers.count} | select name 

Nói chung, tôi sẽ tiếp cận union và intersection trong Powershell như thế này:

$a = (1,2,3,4) 
$b = (1,3,4,5) 
$a + $b | select -uniq #union 
$a | ?{$b -contains $_} #intersection 

Nhưng đối với những gì bạn đang yêu cầu, giải pháp trên hoạt động tốt và không thực sự về công đoàn và giao lộ trong định nghĩa chuẩn của các điều khoản.

Cập nhật:

Tôi đã viết pslinq cung cấp Union-ListIntersect-List giúp để đạt được thiết union và intersection với Powershell.

+0

Các công cụ thú vị, các oneliner này sẽ hoạt động như thế nào với các bộ sưu tập có khóa như Hashtables? – Bastl

+1

Bài đăng tuyệt vời - phải có một thư viện chuẩn cho các mảng cung cấp chức năng như vậy. lodash cho powershell .. – ferr

+1

cho đầy đủ, bạn có thể nhận được sự khác biệt thiết lập giữa $ a và $ b sử dụng $ a | ? {$ b -notcontains $ _} #difference –

11

Bạn cũng có thể làm

$a = (1,2,3,4) 
$b = (1,3,4,5) 
Compare-Object $a $b -PassThru -IncludeEqual     # union 
Compare-Object $a $b -PassThru -IncludeEqual -ExcludeDifferent # intersection 

Không hoạt động nếu $a là null mặc dù.

+1

Có thể thêm $ null vào mảng. $ a = 1,2,3,4, $ null –

10

Đối với bộ trừ (a - b):

$a | ?{-not ($b -contains $_)}

+7

Ngoài ra còn có -không có liên kết. –

3

Trong khi điều này sẽ không làm việc trong các phiên bản sớm nhất, trong các phiên bản gần đây bạn có thể chỉ cần gọi các chức năng mở rộng NET LINQ trực tiếp, ví dụ

[system.linq.enumerable]::union([object[]](1,2,3),[object[]](2,3,4)) 

(Nếu không có các diễn viên đối với một số loại đếm được, PowerShell ném một lỗi "không thể tìm thấy tình trạng quá tải".)

này chắc chắn làm việc trong PowerShell V4 và V5 và chắc chắn không ở V2. Tôi không có một hệ thống trong tay với V3.

Các vấn đề liên quan