Is there a more simple/efficient way to initialize a dictionary from an array in Swift 3?
for object in array {
dict[object.id] = object
}
Nothing wrong with the above but I was wondering if you could use map/reduce/etc to do this with slightly less code.
array.forEach({ object in
dict[object.id] = object
})
or shorter:
array.forEach({ dict[$0.id] = $0 })
Related
This question already has answers here:
For-in loop and type casting only for objects which match type
(2 answers)
Closed 6 years ago.
I'd like to know if it is possible to iterate over an array is swift and check if the current element has a certain type.
A use case would be : I have an array with NSDictionarys and NSArrays and I ony want to take care of the NSDictionarys.
I'd like to do this without the condition inside the loop :
for entity in array
{
if entity is NSDictionary
{
// Do something
}
}
I'm looking for something like :
for (entity in array) as? NSDictionary
{
// Do something
}
Of course I know that what I have just written doesn't work, but I guess you can get the idea of what I'm asking for.
Any idea would be really appreciated !
Solution 1
You can filter your array
let things = [NSDictionary(), NSArray(), NSDictionary(), NSArray()]
let dicts = things.flatMap { $0 as? NSDictionary }
Now dicts is defined as [NSDictionary] an contains only the 2 dictionaries.
Solution 2
You can also perform a for loop only on the values that are dictionaries
let things = [NSDictionary(), NSArray(), NSDictionary(), NSArray()]
for dict in things.flatMap( { $0 as? NSDictionary }) {
}
Using filter with the type check operator is
As an alternative to the flatMap solutions, you may use filter along with the type check operator is:
let arr: [AnyObject] = [NSDictionary(), ["foo", "bar"], NSDictionary(), "foo"]
for dict in arr.filter({ $0 is NSDictionary }) {
// do something with dictionary
}
Use the type check operator (is) to check whether an instance is of
a certain subclass type. The type check operator returns true if the
instance is of that subclass type and false if it is not.
From Swift Language Guide - Type Casting. Since you don't have to worry about subclass matches (you know the elements to be either NSDictionary or NSArray) the is filter approach can be an appropriate alternative here.
Note that when using the flatMap and type cast operator (as), the iterate element in the for loop (dict) will be of type NSDictionary, whereas the filter approach above will perform no downcasting, hence preserving the NSDictionary in its wrapped form, as AnyObject. Probably the flatMap approach is to prefer here.
If you don't care for elements to have the same indexes as in original array, you can flatMap to the required type.
for element in array.flatMap({ $0 as? NSDictionary }) {
// do something
}
I want to create a dictionary out of an array and assign a new custom object to each of them. I'll do stuff with the objects later. How can I do this?
var cals = [1,2,3]
// I want to create out of this the following dictionary
// [1:ReminderList() object, 2:ReminderList() object, 3:ReminderList() object]
let calendarsHashedToReminders = cals.map { ($0, ReminderList()) } // Creating a tuple works!
let calendarsHashedToReminders = cals.map { $0: ReminderList() } // ERROR: "Consecutive statements on a line must be separated by ';'"
map() returns an Array so you'll either have to use reduce() or create the dictionary like this:
var calendars: [Int: ReminderList] = [:]
cals.forEach { calendars[$0] = ReminderList() }
You can also use reduce() to get a oneliner but I'm not a fan of using reduce() to create an Array or a Dictionary.
I have array of arrays grid in my code. what I want to do is checking if there is a object at x, y let object = grid[x][y] if object is not nil I edit it else I assign a new object to it grid[x][y] = newObject().
if let object = grid[x][y] {
object.property = newValue
} else {
grid[x][y] = newObject()
}
but I get fatal error: Array index out of range in the line if let object = grid[x][y] {
what is the best way to do that?
Thanks in advance.
What you need to do (as I said in my comment) is to both allocate the array to the size that you want, and to make it an array of Object? rather than Object (or Object! - why do you do that?). Something like this, for a 2x2 array ...
var grid = [[Object?]](count:2, repeatedValue: [Object?](count:2, repeatedValue:nil))
Firstly, if you want to modify your grid object down the road, you can't define it with let. You must use var.
It looks like you're trying to use optional binding (if let x = Optional(y) { ... }) with array subscripting (array[x]). This won't work, as an array subscript doesn't return an optional. It'll instead return a valid object or throw an exception. You could try this:
if grid.count > x {
if grid[x].count > y {
object = grid[x][y]
}
}
I have two NSMutableArray's
I am trying to remove the MutableArray from other Array with removeObjectsInArray() method
Here is my code:
arrayImage.removeObjectsInArray(arrayDeleteImage)
But it requires a filter (NSPredicate), I don't understand why it's requried.. I have implement the filter but it's giving me an error..
arrayImage = arrayImage.filter //error:Nsmutable does not have member filter
{ value in
!contains(arrayDeleteImage, value) //Implicit use of 'self' in closure; use 'self.' to make capture semantics explicit
}
How can I remove the array objects from the other array ?
Try this:
var arrayOne:[NSMutableArray]
var arrayTwo:[NSMutableArray]
for ar in arrayTwo
{
arrayOne.removeObject(ar)
}
I would like to use a for-in loop.
It's actually really easy. Just use Array(Zip2). After that you can iterate over it:
let theZip = Zip2(["Hi", "up?", "that"], ["whats", "Not", "much"])
let myZipArray = Array(theZip)
//without array
for single in theZip{
println(single)
}
//with array
for single2 in myZipArray{
println(single2)
}