2015-09-16 24 views
36

tôi đang cố gắng để lọc một cuốn từ điển trong nhanh chóng:Swift: lọc từ điển

var data: [String: String] = [:] 
data = data.filter { $0.1 == "Test" } 

mã lọc trên biên dịch dưới nhanh chóng 2 nhưng mang lại các lỗi sau:

Cannot assign a value of type '[(String, String)]' to a value of type '[String : String]' 

là này một lỗi trong trình biên dịch nhanh hay đây không phải là cách đúng để lọc từ điển nhanh chóng?

Cảm ơn bạn rất nhiều trước!

Trả lời

57

này đã được cố định trong Swift 4

let data = ["a": 0, "b": 42] 
let filtered = data.filter { $0.value > 10 } 
print(filtered) // ["b": 42] 

Trong Swift 4, một cuốn từ điển lọc trả về một từ điển.


câu trả lời gốc cho Swift 2 và 3

Vấn đề là data là một cuốn từ điển nhưng kết quả của filter là một mảng, vì vậy thông báo lỗi nói rằng bạn không thể gán kết quả của cái sau đến cái cũ.

Bạn chỉ có thể tạo ra một biến mới/liên tục cho mảng kết quả của bạn:

let data: [String: String] = [:] 
let filtered = data.filter { $0.1 == "Test" } 

Đây filtered là một mảng của các bộ: [(String, String)].

Khi lọc, bạn có thể tái tạo một từ điển mới nếu đây là những gì bạn cần:

var newData = [String:String]() 
for result in filtered { 
    newData[result.0] = result.1 
} 

Nếu bạn quyết định không sử dụng filter bạn có thể biến đổi từ điển gốc hoặc một bản sao của nó:

var data = ["a":"Test", "b":"nope"] 
for (key, value) in data { 
    if value != "Test" { 
     data.removeValueForKey(key) 
    } 
} 
print(data) // ["a": "Test"] 

Lưu ý: trong Swift 3, removeValueForKey đã được đổi tên thành removeValue(forKey:), vì vậy trong ví dụ này nó trở thành data.removeValue(forKey: key).

+19

alright cảm ơn bạn :) đó chỉ là ngu ngốc từ táo theo ý kiến ​​của tôi. Khi tôi lọc từ điển, tôi mong đợi từ điển trở lại ... Tôi đã thay đổi mã của mình thành mảng và sử dụng cấu trúc kết hợp để bao gồm cả khóa và giá trị (để tôi không bị buộc phải sử dụng khóa chuỗi) và hơn tôi sử dụng chức năng lọc một lần nữa, vì đây là cách tiếp cận súc tích nhất. – warly

+4

Bất cứ ai cũng biết tại sao Dictionary.filter không trả lại một từ điển? Tôi tò mò. – Tylerc230

+0

@warly xem câu trả lời của Eendje bên dưới. Đó là một câu trả lời khác nhau – Honey

13
data.forEach { if $1 != "Test" { data[$0] = nil } } 

Chỉ cần một cách tiếp cận khác (đơn giản hóa một chút) để lọc ra các đối tượng trong từ điển của bạn.

7

mỗi docs Apple, bộ lọc:

Returns an array containing, in order, the elements of the sequence that satisfy the given predicate.

https://developer.apple.com/reference/swift/sequence/1641239-filter

tôi thấy mình cần phải làm những gì OP được hỏi về và kết thúc bằng văn bản cho phần mở rộng sau (Swift 3):

extension Dictionary 
{ 
    func filteredDictionary(_ isIncluded: (Key, Value) -> Bool) -> Dictionary<Key, Value> 
    { 
    return self.filter(isIncluded).toDictionary(byTransforming: { $0 }) 
    } 
} 

extension Array 
{ 
    func toDictionary<H:Hashable, T>(byTransforming transformer: (Element) -> (H, T)) -> Dictionary<H, T> 
    { 
    var result = Dictionary<H,T>() 
    self.forEach({ element in 
     let (key,value) = transformer(element) 
     result[key] = value 
    }) 
    return result 
    } 
} 

Cách sử dụng:

let data = ["a":"yes", "b":"nope", "c":"oui", "d":"nyet"] 
let filtered = data.filteredDictionary({ $0.1 >= "o" }) 

// filtered will be a dictionary containing ["a": "yes", "c": "oui"] 
0

tôi đã tìm thấy phương pháp này để có ích sau khi lọc hoặc áp dụng một số khác biến đổi có kết quả trong một loạt các yếu tố từ điển:

extension Array { 
    func dictionary<K: Hashable, V>() -> [K: V] where Element == Dictionary<K, V>.Element { 
     var dictionary = [K: V]() 
     for element in self { 
      dictionary[element.key] = element.value 
     } 
     return dictionary 
    } 
} 

Để sử dụng nó, chỉ cần nói cái gì đó như:

dictionary = dictionary.filter{ $0.key == "test" }.dictionary() 

Lợi thế của phương pháp này là không có đối số thuộc loại nào cần được chuyển đến phương pháp dictionary(). Đối số kiểu chung cho trình biên dịch mọi thứ cần biết.

+0

Tôi không thể biên dịch với chương trình này lỗi này: 'Hiển thị tất cả các sự cố /Users/XXXX/Desktop/Work4/BitBucketRepo/XXXX-XXX/XXXXX/XXXXX/Sources/Utils/Extensions/NSArray+Utils.swift:12 : 63: Yêu cầu cùng loại làm cho thông số chung 'Yếu tố' không chung chung ' '/ Người dùng/XXXX/Máy tính để bàn/Work4/BitBucketRepo/XXX-XXX-XXX/XXXXX/XXXXX/Nguồn/Utils/Tiện ích mở rộng/NSArray + Utils .swift: 15: 24: Giá trị của loại 'Element' không có thành viên 'key'' –

+0

@ReinierMelian: Tôi không biết bạn đang gặp phải vấn đề gì. Dán nội dung của [mã này] (https://pastebin.com/FA9vvv15) vào Xcode Playground và bạn sẽ thấy nó hoạt động hoàn hảo. Đảm bảo bạn đang sử dụng phiên bản mới nhất của Swift. –

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