2012-07-06 28 views
7

Tôi đang có bảng băm trong đó Khóa đang được sử dụng dựa trên giá trị.Làm cách nào để lấy khóa bảng băm có giá trị cụ thể?

Ví dụ:

[email protected]{"ComponentNameX"="True"; 
          "ComponentNameXyz"="False"; 
          "SomeComponent"="False"} 

Tôi muốn nhận các khóa có giá trị True. (Tôi sẽ chuyển khóa cho một số tập lệnh khác làm tham số).

Tôi đã cố gắng như vậy, Nhưng tôi nghĩ rằng một số nơi tôi đang thiếu vì nó không phải là danh sách các phím.

$($ComponentToBuild.Keys) | Where-Object { $_.Value -eq "True" } 

Làm cách nào để lấy tên thành phần được ký hiệu là True? Ngoài ra tôi muốn biết liệu bảng băm là một lựa chọn khôn ngoan cho loại công việc này. Bởi vì tôi nghĩ rằng bảng băm sẽ được sử dụng chủ yếu để xử lý các giá trị.

Trả lời

8

Xin chào điều này sẽ phù hợp với những gì bạn muốn.

[email protected]{"ComponentNameX"="Test"; 
          "ComponentNameXyz"="False"; 
          "SomeComponent"="False"}      

Foreach ($Key in ($ComponentTobeBuild.GetEnumerator() | Where-Object {$_.Value -eq "Test"})) 
{$Key.name} 
+0

Tập lệnh này đang cố gắng lấy giá trị, thực ra tôi đã cố gắng lấy khóa. Nhưng việc này cũng không hiệu quả. $ ComponentTobeBuild.Keys | Ở đâu-đối tượng {$ _ -eq "True"} – Samselvaprabu

+0

O ok xin lỗi tôi đã thay đổi mã kiểm tra nếu nó hoạt động ngay bây giờ.ps sao chép mã hoàn chỉnh và cung cấp cho nó một thử, bạn có thể đặt mã trong phần "{$ Key.name}" để đặt tất cả các khóa có giá trị kiểm tra vào bảng băm khác nếu bạn thích – justinf

11
$ComponentTobeBuild.GetEnumerator() | ?{ $_.Value -eq "True" } 
6

Tôi biết điều này là cũ, nhưng tôi thấy điều này trên tìm kiếm của tôi cho một vấn đề khác và tự hỏi tại sao bạn bận tâm với điều tra viên. Chỉ cần tạo mã chính xác như câu hỏi bằng ngôn ngữ thực:

Cho tôi tất cả các khóa, trong đó giá trị là 'Đúng'.

$ComponentTobeBuild.Keys | ? { $ComponentTobeBuild[$_] -eq 'True' } 

Vì mục đích nhất quán, tôi sẽ đóng gói trong @() để lấy một mảng ngay cả khi chỉ có một hoặc không có kết quả.

Đối với giải pháp người hỏi có, vấn đề là $_ là một chuỗi và .Value không phải là giá trị của khóa. Nó đơn giản không tồn tại trong một String. Bạn phải lấy giá trị của hashtable với $_ làm Khóa để so sánh nó.

+0

Điều này có thể gây ra bất ngờ hành vi khi bộ sưu tập có nhiều mục nhập với cùng một khóa ... –

+0

@ oɔɯǝɹ trong Powershell bạn không thể tạo hastable với các khóa không độc đáo – maoizm

+0

@maozim Tôi nghĩ rằng chúng tôi đang sử dụng thuật ngữ hashtable sai, vì chúng tôi đang sử dụng cơ sở dữ liệu từ điển/bản đồ trong câu hỏi. Hashtables trong .net có thể có xung đột và sẽ sử dụng danh sách được liên kết để lưu trữ nhiều mục dưới cùng một mã băm. Một hashtable là tất cả về việc thu hồi theo đối tượng. Một từ điển sử dụng các khóa duy nhất –

3

Sự cố khi lọc Hashtables trong PowerShell là bạn không thể lặp qua các cặp khóa-giá trị.

Hãy nói rằng bạn có một số bộ sưu tập:

$collection = @{ 
    a = 'A'; 
    b = 'B'; 
    c = 'C'; 
    d = 'D'; 
    e = 'E'; 
    ... 
} 

Bạn mong chờ để có thể sử dụng

$results = $collection | Where-Object { $_.Key -in ('a', 'b', 'd') } 

trong PowerShell, nhưng điều đó là không thể.

Vì vậy, bạn có quay lại sử dụng các điều tra viên:

$results = $collection.GetEnumerator() | Where-Object { $_.Key -in ('a', 'b', 'd') } 
$results 

Name       Value 
----       ----- 
d        D 
b        B 
a        A 
+0

Bất kỳ ai cũng có thể cung cấp lý do tại sao .keys không thể được lặp lại hoặc lập chỉ mục như các bộ sưu tập khác? Loại của nó là Hashtable + keyCollection, ít nhất nó ngụ ý đó là một loại bộ sưu tập. – BobHy

0

Bạn cũng có thể sử dụng 'Where phương pháp Dictionary.Keys mà trả về tất cả các yếu tố mà một điều kiện đúng. Điều kiện đó có thể là một lambda khẳng định rằng khóa được kiểm tra $_ liên quan đến giá trị "True" trong từ điển.

[email protected]{"ComponentNameX"="True"; 
         "ComponentNameXyz"="False"; 
         "SomeComponent"="False"} 
$ComponentTobeBuild.Keys.Where({$ComponentTobeBuild[$_] -eq "True"}) 
# -> @("ComponentNameX") 
Các vấn đề liên quan