Swift add all elements from array together - ios

I have an array of numbers and I want to iterate through all of the elements in that array and add together all of the integers. Here is the function I have so far:
func addTogether(array:Array<Int>, divide:Int) -> Int
{
var a = 0
while a < array.count
{
}
return 0
}
I know that I'm probably going to have to do this inside of the while loop. Can anyone give me some guidance as to where to go from here? Thanks!

No loop needed. Use reduce, like this:
let sum = array.reduce(0,+)

Related

(Swift) moving objects while iterating over array

I am trying to remove some objects from 1 array, and move them to another.
I am doing this by removing them from a reversed array, and adding them to another array, like so:
var array1 = [1,2,3,4,5,6]
var array2 = [1,2]
for (index, number) in array1.enumerated().reversed() {
if(number>2) {
array1.remove(at: index)
array2.append(number)
}
}
The problem is, the objects in array 2 are obviously reversed (1,2,6,5,4,3)
I can easily come up with complicated workarounds, but I was wondering if there are any straightforward ways of doing this.
Thanks in advance!
Rather than appending the numbers insert them
array2.insert(number, at: 2)
You can do the same thing without a loop
let droppedItems = array1.dropFirst(2)
array1.removeLast(array1.count - 2)
array2.append(contentsOf: droppedItems)
If I understand you correctly, you want to move numbers from array1 to array2 if they are higher than 2:
// get only numbers higher than 2 and append them to the second array
array2.append(contentsOf: array1.filter { $0 > 2 })
// filter the moved items from the first array
array1 = array1.filter { $0 <= 2 }
or
// split the array into two parts in place
let index = array1.partition { $0 > 2 }
// move the second part
array2 += array1[index...]
// remove the second part
array1.removeSubrange(index...)
Reverse it, grab subarray then append to array2. You don't need to mutate array1. Something like:
array2.append(contentsOf: array1.reversed()[0..<array1.count-1])

Iterate through an optional array in Swift?

I'm using the cocoapod SQLite for this project like so
import SQLite
var db = try! Connection()
var id: Expression<Int>!
var identifier: Expression<String>!
With it I am reading a list of moves from a SQLite database.
Every monster has a moves that they can learn. Some monsters can learn more moves than others.
var monster: Monster!
var monArray = [Monster]()
var dataSource: DataSource!
To get the monsters move ID I use this code. This allows me to grab the first move in the array. Changing the 0 would get me the second, third move ect.
monster.moves![0]["move_id"] as! Int
Now I'm using the SQLite database because I need to match monster ID values in my plist with the ones in the SQLite database. I use this code to do so
override func viewWillAppear(_ animated: Bool) {
let movesArray = Array(try! db.prepare(Table("moves").where(identifier == moves.name!.lowercased())))
for user in movesArray {
monArray = dataSource.mons.filter{ $0.moves![0]["move_id"] as! Int == user[id] }
}
}
Everything works fine until I try to increase the index range.
for user in movesArray {
for i in 0...6 {
monArray = dataSource.mons.filter{ $0.moves![i]["move_id"] as! Int == user[id] }
}
}
See where I replace the 0 with the range i? I do that because since monsters have more than one move, if I leave it at 0 my app will only display the monsters that learn that move as their first move. To better explain, my current code does not look through whether the monster knows the move, it only looks through whether the monsters knows the move as its first move.
In the above code I increase the range thinking it would solve my issue, but my app will crash because some monsters only have 1 move in their index, so anything above index 0 will crash with the error
fatal error: Index out of range
So to recap, I need to iterate through the entire array instead of just the first index, without it crashing. How can I achieve this?
Without all the story arround your just asking how to iterate over an array like here
for item in array as type {
...
}
Your question seems to be more of a logical question. If I'm understanding what you have said, then each monster will have a minimum of 1 move, but not guaranteed to have more. So you would need to account for this.
Having a fixed limit like you do will certainly cause problems if not all monsters have that many moves as the array will not always be that size.
I would do something like:
let monsterMoveCount = user.moves.count
for i in 0...monsterMoveCount
// Do whatever logic here
Hopefully this helps!

Filter an array by NOT containing string (swift 2)

I am relatively new to swift; I am working on filtering arrays.
I know how to filter out elements of an array that contain a letter (like so: let filteredList = wordlist.filter { !$0.characters.contains(letter) }), but how do I filter out elements that do not have a letter?
Here's what I want to accomplish:
I have a word list in string-array format, i.e. ["thing", "other thing"] (but much longer), and I want to return every element that has a certain letter, filtering out the ones that do not have a certain letter.
Thanks in advance.
This was a silly question, I am sorry. Anyway, I just needed to remove the exclamation mark. So...
let filteredList = wordlist.filter { !$0.characters.contains(letter) }
// returns elements in the array WITHOUT "letter".
let filteredList = wordlist.filter { $0.characters.contains(letter) }
// returns elements in the array WITH "letter".
Thanks Eendje.

run function depending on passed integer in swift

I want to run different functions depending on selected level Integer
so if selected level is 1 then runfunc1(), if 2 then runfunc2()...
I know this is possible using if else
if levelselected == 1 {
runfunc1()
} else if levelseletecd == 2 {
runfunc2()
// ... and so on
}
Is there any better way than this, perhaps something like this
runfunc%i(),levelselected // I know its not correct but something similar
I dont want to write new code for every level, so any better way?
You can use something like:
var levelSelected = 0 //
var selector = Selector("runFunc\(levelSelected)")
if self.respondsToSelector(selector) {
NSThread.detachNewThreadSelector(selector, toTarget: self, withObject: nil)
}
You could have an array or dictionary of functions. A dictionary might be nicer since the logic for checking if the level is valid is a lot simpler:
let funcs = [1: runfunc1, 2: runfunc2]
if let funcToRun = funcs[levelselected] {
funcToRun()
}
However, you won't be able to easily dynamically build a function name from strings and numbers without using #objc functionality.
(except in the sense that you could make the key to the dictionary a string of the function name, but you still have to build the dictionary using actual function names determined at compile time)
That said, you can add to the funcs variable from elsewhere in the code so it does mean to can "hook up" new levels without changing this dispatching logic.
Not the exact solution you are looking for but this can make it easier :
Declare an array of the desired functions:
var levelFunctions: [()->()] = [runfunc1, runfunc2, runfunc3]
This syntax declares an array of functions that have zero argument and return nothing. You initialize this array with the required function names and then execute the desired function using the levelselected variable:
levelFunctions[levelselected]() // Or levelselected-1 if the variable is not zero-based
EDIT:
As Airspeed Velocity mentioned in the comment and his answer you should make sure the level is in the array bounds.
I prefer to create a function, for example runFuncFromLevel::Int -> (() -> Void). runFuncFromLevel return a proper function that you need.
func runFuncFromLevel(level: Int) -> () -> Void
{
switch level
{
case 1: return runfunc1
case 2: return runfunc2
default: return {}
}
}

Best way to init an array of views in swift?

I'm writing a new subclass of UIView using swift. I want to have an array of views, and I want to instantiate them in the initial declaration, for clarity.
If this was an Int array, I could do something like this:
let values: [Int] = (0...4).map() { $0 }
and so I'm trying to come up with some sort of similarly swifty one-liner that will create an array of UIButtons, instead of Ints.
my first thought was (0...4).map() { UIButton.buttonWithType(.Custom) } but if I do this (or if I replace the UIButton code with, say NSObject()) I get an error saying that "'Transition' does not have a member named 'map'". I can, say, do map() { "\($0)" } and get an array of strings.
My next thought was just to get an array of ints first, and then use map on those to return buttons, like:
let values: [UIButton] = (0...4)
.map() { $0 }
.map() { UIButton.buttonWithType(.Custom) }
but this gives me the same error. What am I doing wrong, here?
Okay, the solution came to me pretty quickly: I guess I can't quietly ignore the variable of the closure I'm passing in to the map function; I need to ignore it explicitly. So to get my array of 4 buttons, I can use an _ in the map function, like this:
var buttons = (0...4).map() {_ in UIButton.buttonWithType(.Custom) }
or what I actually ended up using:
lazy var buttons: [UIButton] = (0...4).map() { _ in
let button = UIButton.buttonWithType(.Custom) as UIButton
self.addSubview(button)
return button
}

Resources