2012-03-22 25 views
10

Vì vậy, chúng ta hãy nói rằng tôi có mảng này:Trong Powershell làm thế nào tôi có thể kiểm tra xem tất cả các mục từ một mảng tồn tại trong một mảng thứ hai?

$requiredFruit= @("apple","pear","nectarine","grape") 

Và tôi cung cấp một mảng thứ hai gọi là $fruitIHave. Làm cách nào để kiểm tra xem $fruitIHave có mọi thứ trong số $requiredFruit hay không. Nó không quan trọng nếu có nhiều mặt hàng trong $fruitIHave chỉ miễn là tất cả mọi thứ trong $requiredFruit là có.

Tôi biết tôi chỉ có thể lặp qua danh sách, nhưng điều đó có vẻ không hiệu quả, có phương pháp tích hợp để thực hiện việc này không?

Trả lời

24

Bạn thử so sánh-Object :

$requiredFruit= @("apple","pear","nectarine","grape") 
$HaveFruit= @("apple","pin","nectarine","grape") 
Compare-Object $requiredFruit $haveFruit 
InputObject             SideIndicator 
-----------             ------------- 
pin               => 
pear              <= 

Compare-Object $requiredFruit $haveFruit | where {$_.sideindicator -eq "<="} | % {$_.inputobject} 
pear 
1

Không chính xác "dựng sẵn" nhưng:

[regex] $RF_regex = ‘(?i)^(‘ + (($requiredFruit |foreach {[regex]::escape($_)}) –join “|”) + ‘)$’ 

($fruitIHave -match $RF_regex).count -eq $requiredFruit.count 

Điều đó tạo ra một regex xen kẽ từ các yếu tố của $ requiredFruit. Được so sánh với $ fruitIHave, nó sẽ trả về tất cả các mục phù hợp. Nếu $ fruitIhave có thể có khả năng có bản sao của cùng một loại trái cây, bạn có thể cần phải chạy kết quả phù hợp đó thông qua get-unique trước khi bạn thực hiện đếm. Nó có thể chậm hơn so với lặp qua danh sách cho một so sánh duy nhất, nhưng một khi bạn đã xây dựng regex nó sẽ làm các trận đấu lặp đi lặp lại rất hiệu quả.

0

Cách này hay cách khác, bạn sẽ phải lặp qua một hoặc cả hai mảng. Dưới đây là một cách tiếp cận một liner:

$hasAllRequiredFruit = ($requiredFruit | Where-Object { $fruitIHave -contains $_ }).Length -eq $requiredFruit.Length; 

Một vòng lặp foreach sẽ tốt hơn vì bạn có thể dừng iterating ngay sau khi bạn tìm thấy một quả đòi hỏi là mất tích:

$hasAllRequiredFruit = $true; 
foreach ($f in $requiredFruit) 
{ 
    if ($fruitIHave -notcontains $f) 
    { 
     $hasAllRequiredFruit = $false; 

     break; 
    } 
} 
+1

@ Đồng nghĩa Hèn nhát: Tại sao bạn bỏ phiếu? – BACON

11

Nếu bạn có các mảng:

$requiredFruit= @("apple","pear","nectarine","grape") 
$someFruit= @("apple","banana","pear","nectarine","orange","grape") 
$moreFruit= @("apple","banana","nectarine","grape") 

Bạn có thể có được một kết quả boolean với:

'Check $someFruit for $requiredFruit' 
-not @($requiredFruit| where {$someFruit -notcontains $_}).Count 

'Check $moreFruit for $requiredFruit' 
-not @($requiredFruit| where {$moreFruit -notcontains $_}).Count 

Sử dụng đếm của một mảng bảo vệ chống lại một giá trị duy nhất không phù hợp mà đánh giá như False. Ví dụ:

# Incorrect result 
-not (0| where {(1,2) -notcontains $_}) 

# Correct result 
-not @(0| where {(1,2) -notcontains $_}).Count 

Với PowerShell v3, bạn có thể sử dụng select -first 1 để ngăn chặn các đường ống khi không phù hợp đầu tiên được tìm thấy (trong v2 select -first 1 cho phép chỉ có một đối tượng thông qua, nhưng các yếu tố trước của đường ống tiếp tục xử lý).

-not @($requiredFruit| where {$moreFruit -notcontains $_}| select -first 1).Count 
Các vấn đề liên quan