Swift filter dictionary error: Cannot assign a value of type '[(_, _)]' to a value of type '[_ : _]'
This has been fixed in Swift 4
let data = ["a": 0, "b": 42]
let filtered = data.filter { $0.value > 10 }
print(filtered) // ["b": 42]
In Swift 4, a filtered dictionary returns a dictionary.
Original answer for Swift 2 and 3
The problem is that data
is a dictionary but the result of filter
is an array, so the error message says that you can't assign the result of the latter to the former.
You could just create a new variable/constant for your resulting array:
let data: [String: String] = [:]
let filtered = data.filter { $0.1 == "Test" }
Here filtered
is an array of tuples: [(String, String)]
.
Once filtered, you can recreate a new dictionary if this is what you need:
var newData = [String:String]()
for result in filtered {
newData[result.0] = result.1
}
If you decide not to use filter
you could mutate your original dictionary or a copy of it:
var data = ["a":"Test", "b":"nope"]
for (key, value) in data {
if value != "Test" {
data.removeValueForKey(key)
}
}
print(data) // ["a": "Test"]
Note: in Swift 3, removeValueForKey
has been renamed removeValue(forKey:)
, so in this example it becomes data.removeValue(forKey: key)
.
Can't assign value of type Dictionary to LazyMapCollection
It may be that Dictionary.keys
returned a LazyMapCollection
in earlier Swift versions. In Swift 5 it is Dictionary
as can be seen from the documentation, in your case
var answerKeys: Dictionary.Keys
But note that you can always access answer.keys
in your code instead of assigning this to a separate property.
Swift filter and dictionaries
Just do it like this:
var namesAndAges = ["Tom": 25, "Michael": 35, "Harry": 28, "Fabien": 16]
var underAge = namesAndAges.filter({ $0.value < 18 }) // [(key: "Fabien", value: 16)]
What you do is that you use $0.value
in your filter
.
Cannot assign value of type '[String]' to type '[[String : Any]]'
It looks like you are trying to create a filtered list based on a search term, but your dicSearch
type is an array of string
s (i.e: [String]
), while your searchingDic
is an array of dictionaries (i.e: [[String : Any]]
).
This might be confusing when coming from a different language, but in Swift, the following declaration is a dictionary:
var dict: [String: Any] = [
"key1": "value1",
"key2": "value2",
]
so the following:
var arrayOfdicts: [[String: Any]] = [
["foo": "bar"],
["apples": "oranges"],
dict
]
is actually an array, containing a list of dictionaries, notice how I've put the dict declared above in the second array.
The compiler is telling you that you cannot assign a '[String]' to type '[[String : Any]]'
because this:
// example to an array of strings
var fullList: [String] = [
"apples",
"bananas",
"cucumbers"
]
// is not the same as
var arrayOfdicts: [[String: Any]] = [
["foo": "bar"],
["apples": "oranges"],
dict
]
The Array#filter
method, iterates the array itself, and returns a new array with only the elements that return true
in the return statement.
so either both your arrays need to be [String]
or both your arrays need to be [[String:Any]]
example for String arrays:
// array
var fullList: [String] = [
"apples",
"bananas",
"cucumbers"
]
var filteredList: [String] = []
var searchTerm = "b"
filteredList = fullList.filter{ item in
let value = item
return value.lowercased().contains(searchTerm)
}
print(filteredList) // prints ["bananas", "cucumbers"]
an example for filtering with array of dictionaries:
var people: [[String: Any]] = [
["name": "Joe"],
["name": "Sam"],
["name": "Natalie"],
["name": "Eve"]
]
var filteredPeople: [[String: Any]] = []
var nameFilter = "a"
filteredPeople = people.filter{ item in
let value = item["name"] as! String
return value.lowercased().contains(nameFilter)
}
print(filteredPeople) // prints [["name": "Sam"], ["name": "Natalie"]]
Hope this helps :)
Sorting Array returns a Dictionary
I didn't get any solution for the same to sort the dictionary, but you can do something like below.
Its works for me.
make structure of key and value.
struct STRUCT_TEMP
{
var key : Int
var value : [MyCustomModel]
}
create structure variable.
var structTemp : [STRUCT_TEMP] = []
convert your dictionary in structure like below:
self.structTemp = datasource.map({ STRUCT_TEMP(key: $0.key, value: $0.value) })
now you can do anything with the structTemp array. Like sorting, filter and you can also use this array everywhere you want instead of dictionary.
How to assign value to dictionary saved as Any in Swift?
The result of the type cast is immutable, you have to assign the result to a variable
var learning: Any = [ "name": "C++" ]
var dictionary = learning as! [String: String]
dictionary["name"] = "Swift"
By the way Any
is the worst choice
Related Topics
Invalid Swift Support - Files Don't Match
Xcodebuild Different Provisioning Profile for Target Dependency
How to Define Optional Methods in Swift Protocol
How to Create a Scroll View with a Page Control Using Swift
How to Use Avcapturephotooutput
Why Storyboard UI Elements Not Showing on Uiviewcontroller in Xcode 6
How to Resize Uiimageview Based on Uiimage's Size/Ratio in Swift 3
The Code Signature Version Is No Longer Supported
Uitableview Mix of Static and Dynamic Cells
Xcode Beta 6 iOS 8: Simulator Not Working
Afnetworking 3.0 Migration: How to Post with Headers and Http Body
Change Tab Bar Item Selected Color in a Storyboard
Swift 2: Call Can Throw, But It Is Not Marked with 'Try' and the Error Is Not Handled
How to Use Nslocalizedstring Function with Variables in Swift
Restrict to Certain iOS Target Devices for App Store Submission
iOS Perform Action After Period of Inactivity (No User Interaction)