Reduce to count elements in a dictionary in Swift - swift

I'm trying to count the elements of my dictionary. The dictionary is of type [EKCalendar: ReminderList] where ReminderList is a class with a list property. I want to go through the dictionary and add up the count of all these lists.
My dictionary is in the property self?.reminderListsStructure.structure.
let numberOfElements = self?.reminderListsStructure.structure.reduce(0) {
accumulator, nextValue in
return accumulator.list.count + nextValue.list.count
// COMPILE ERROR: Type of expression is ambiguous without more context
}

let count = reminderListsStructure.structure.reduce(0) { $0 + $1.1.list.count }
Something like this. Not enough info though, so I'm not 100% sure it works.

I think flatMap is a more appropriate choice here:
let input = [
1: [1],
2: [1, 2],
3: [1, 2, 3],
4: [1, 2, 3, 4],
5: [1, 2, 3, 4, 5]
]
let output = input.values.flatMap{$0}.count //15

When you reduce a dictionary, the element type is a tuple of the Key and Value types, so you can use:
dictionary.reduce(0) { $0 + $1.1.list.count }
Or, you can get just the values from the dictionary and reduce that:
dictionary.values.reduce(0) { $0 + $1.list.count }
Note that since Dictionary.values returns a lazy iterator, there's not really a huge cost to using it.

More simple and clear way goes like this,
var dict = ["x" : 1 , "y" : 2, "z" : 3]
let count = dict.reduce(0, { x, element in
//maybe here some condition
//if(element.value > 1){return x}
return x + 1
})

Related

Find nearest smaller number in array

I would like to be able to find the nearest smaller value in an array of numbers. For instance, if I have:
[1, 4, 6, 9, 14, 39]
And I'm looking for the nearest value smaller than:
8
The function would return:
6
Additionally, if I pass a number greater than the maximum value in the array, it should return the maximum. If I pass a number smaller than the minimum, it should return nil.
I tried doing this using the first function on arrays, however this on its own doesn't produce the result I'm looking for as I would need something like this:
numbers.first(where: { $0 <= target && $1 < target })
but unfortunately, this isn't valid. Any suggestions? I know this could be done fairly trivially with a while loop, however I was hoping there would be a cleaner, functional way.
Given that the array is sorted , You need
if let value = numbers.last(where: { $0 <= target }) {
print(value)
}
This is a generic solution using binary search. The array must be sorted
extension RandomAccessCollection where Element : Comparable {
func lowerElement(of value: Element) -> Element? {
var slice : SubSequence = self[...]
while !slice.isEmpty {
let middle = slice.index(slice.startIndex, offsetBy: slice.count / 2)
if value < slice[middle] {
slice = slice[..<middle]
} else {
slice = slice[index(after: middle)...]
}
}
return slice.startIndex == self.startIndex ? nil : self[self.index(before: slice.startIndex)]
}
}
let array = [1, 4, 6, 9, 14, 39]
let result = array.lowerElement(of: 8)
print(result)

Get value from array that is closest to but small than another value [duplicate]

I would like to be able to find the nearest smaller value in an array of numbers. For instance, if I have:
[1, 4, 6, 9, 14, 39]
And I'm looking for the nearest value smaller than:
8
The function would return:
6
Additionally, if I pass a number greater than the maximum value in the array, it should return the maximum. If I pass a number smaller than the minimum, it should return nil.
I tried doing this using the first function on arrays, however this on its own doesn't produce the result I'm looking for as I would need something like this:
numbers.first(where: { $0 <= target && $1 < target })
but unfortunately, this isn't valid. Any suggestions? I know this could be done fairly trivially with a while loop, however I was hoping there would be a cleaner, functional way.
Given that the array is sorted , You need
if let value = numbers.last(where: { $0 <= target }) {
print(value)
}
This is a generic solution using binary search. The array must be sorted
extension RandomAccessCollection where Element : Comparable {
func lowerElement(of value: Element) -> Element? {
var slice : SubSequence = self[...]
while !slice.isEmpty {
let middle = slice.index(slice.startIndex, offsetBy: slice.count / 2)
if value < slice[middle] {
slice = slice[..<middle]
} else {
slice = slice[index(after: middle)...]
}
}
return slice.startIndex == self.startIndex ? nil : self[self.index(before: slice.startIndex)]
}
}
let array = [1, 4, 6, 9, 14, 39]
let result = array.lowerElement(of: 8)
print(result)

Swift: Working with for and array

I started to learn Swift but I have some problems like I want to sum two arrays and put them in a third array and I have to do it with for loop.
var ar1 = [1,3,5,7,9]
var ar2 = [2,4,6,8,10]
var ar3 : [Int] = [5]
for i in 0... ar1.count-1 {
// for loop for index
ar3[i] = ar1[i] + ar2[i]
}
But I get an out of range error. I tried a lot but I could not solve it.
Your code looks more like C or Java than swift, but you're on the right track. There are many other ways to do this, but this code is very similar to what you were trying to do:
func example() {
let array1 = [1, 3, 5, 7, 9]
let array2 = [2, 4, 6, 8, 10]
var array3 = [Int]()
for i in 0 ..< array1.count {
array3.append(array1[i] + array2[i])
}
for element in array3 {
print("\(element)")
}
}
Use "let" if the variable never changes once you defined it.
I added a loop at the bottom so you can verify the results, and also so you can see that you don't need "i" in loops.

Add new key value to all the elements in array of dictionary

I have a array of dictionary.
I need to add a new key and a value to all the elements of array of dictionary.
Please guide.
You need to extract the dictionary from the array, modify it and put back to the array, since arrays and dictionaries in Swift are value types.
Something like this should work for you:
var arrayofDict = [["1": 1], ["2": 2], ["3": 3]]
for i in 0..<arrayofDict.count {
var dict = arrayofDict[i]
dict["random"] = Int(arc4random_uniform(8)) //random integer value
arrayofDict[i] = dict
}
print(arrayofDict) //prints "[["1": 1, "random": 2], ["2": 2, "random": 0], ["random": 2, "3": 3]]\n"

Adding integers from a dictionary together

Looking to add together integers from a dictionary. For example:
var dictionary = ["one": 1, "two": 2, "three": 3, "four": 4, "five": 5]
I would want to get the sum of 1+2+3+4+5 = 15
I understand it will probably need a loop something like
for (n, i) in dictionary {
*some math function*
}
any help would be appreciated maybe I'm just over thinking this one?
You can use reduce:combine: to get the sum.
With Swift 2.0, reduce:Combine: is added to the protocol extension of SequenceType. So, it is available to all SequenceType like Array, Set or Dictionary.
dictionary.reduce(0) {
sum, item in
return sum + item.1
}
item inside the closure is tuple representing each (key, value) pair. So, item.0 is key where as item.1 is value.The initial value of the sum is 0, and then each time the iteration takes place, sum is added to the value extracted from dictionary.
You could also write it in short as,
dictionary.reduce(0) { return $0 + $1.1 }
While older version of Swift, it has reduce method with Array only. So, we could first get array and apply reduce:combine to get the sum as,
let a = dictionary.values.array.reduce(0) { return $0 + $1 }