Swift Higher order functions [duplicate] - swift

This question already has answers here:
Beginner Swift 3: How to find pairs in array that add up to given number
(4 answers)
Closed 4 months ago.
I have the following problem,
I want to get the pair of given sum by using higher order functions. I am able to do this using iterative approach. Can someone help me to solve the problem using Swift higher order functions like map, filter etc.
let array = [1,2,3,4,5]
let givenSum = 9
for i in 0..<array.count {
let j = i + 1
for j in j..<array.count {
if array[i] + array[j] == givenSum {
print("Pair : \(array[i]),\(array[j])")
}
}
}
The output is [4,5]
Any help is appreciated. Thank you

let array = [1,5,2,3,4]
let givenSum = 9
let resultArray = array.sorted().filter{ array.firstIndex(of: givenSum-$0) ?? -1 > array.firstIndex(of: $0)!}.map{ ($0 , givenSum - $0)}
print((resultArray))
The above code gives you the expected result with higher order functions (I did not check it for lots of cases).

#Ajay K I think we need to use for loop in any way to implement this solution
Still, you can use the following improved solution
var map = [Int: Int]()
for (i, n) in array.enumerated() {
let diff = givenSum - n
if let j = map[diff] {
print("Pair : \(array[i]),\(array[j])")
}
map[n] = i
}
Happy Coding. Open for thoughts!

Related

Calculator is not taking the Average

I was coding a calculator app on swift, and I am very new to swift. So I am lost with the syntax and everything. When I debug my code I get and error of on the code sayign division by 0. I have debugged and everything but I have no idea how to solve it any help would be greatly appreciated, I am just starting out swift and iOS. The application I am making right is for the mac terminal so my program takes the the users input from string and then converts it to an int.
This is the code I am working with
var average = 0;
let count = nums.count - 1
for index in 0...nums.count - 2 {
let nextNum = Int(nums[index])
average += nextNum!
}
return average / count
}
You are subtracting one from the array elements count, I assume due to the idea that zero based numbering affects it, but there is no need in this case.
You should check for an empty array since this will cause a division by zero. Also you can use reduce to simply sum up an array of numbers then divide by the count.
func average(of nums: [Float]) -> Float? {
let count = nums.count
if (count == 0) { return nil }
return nums.reduce(0, +) / Float(count)
}
There might be some reason for divisor be 0. As #MartinR said if there is only 1 object in nums then count = nums.count -1 would be zero and 1 / 0 is an undefined state.
One more issue I found that you are looping as 0...nums.count - 2 but it should be 0...nums.count - 1. You can also write it with less than condition as
0..<nums.count or 0..<count
Use,
var average = 0;
let count = nums.count
for index in 0..<count {
let nextNum = Int(nums[index])
average += nextNum!
}
return average / count
You can use the swift high-order functions for the optimised solution which will return 0 as average even if you do not have any number in your nums array. As:
let count = nums.count
let avg = nums.reduce(0, +) / count
Let try this:
var sum = 0;
let count = nums.count
for index in 0...nums.count - 1 {
let nextNum = Int(nums[index])
sum += nextNum!
}
return count != 0 ? sum/count : 0

Two different random generated numbers in Swift [duplicate]

This question already has answers here:
How to generate a random number in Swift without repeating the previous random number?
(5 answers)
Closed 5 years ago.
I want that my two random generated labels does not generate the same number like 5 and 5
I have done everything else but this
else if rightScoreLabel == leftScoreLabel {
// what goes here?
{
sorry i’m starter
Try approaching this another way: keep generating new numbers until you have two different values.
var a = 0
var b = 0
while a == b {
a = Int(arc4random_uniform(10))
b = Int(arc4random_uniform(10))
}
Alternatively, you can regenerate just one of the numbers:
var a = Int(arc4random_uniform(10))
var b = 0
repeat {
b = Int(arc4random_uniform(10))
} while a == b

Can this be more Swift3-like?

What I want to do is populate an Array (sequence) by appending in the elements of another Array (availableExercises), one by one. I want to do it one by one because the sequence has to hold a given number of items. The available exercises list is in nature finite, and I want to use its elements as many times as I want, as opposed to a multiple number of the available list total.
The current code included does exactly that and works. It is possible to just paste that in a Playground to see it at work.
My question is: Is there a better Swift3 way to achieve the same result? Although the code works, I'd like to not need the variable i. Swift3 allows for structured code like closures and I'm failing to see how I could use them better. It seems to me there would be a better structure for this which is just out of reach at the moment.
Here's the code:
import UIKit
let repTime = 20 //seconds
let restTime = 10 //seconds
let woDuration = 3 //minutes
let totalWOTime = woDuration * 60
let sessionTime = repTime + restTime
let totalSessions = totalWOTime / sessionTime
let availableExercises = ["push up","deep squat","burpee","HHSA plank"]
var sequence = [String]()
var i = 0
while sequence.count < totalSessions {
if i < availableExercises.count {
sequence.append(availableExercises[i])
i += 1
}
else { i = 0 }
}
sequence
You can overcome from i using modulo of sequence.count % availableExercises.count like this way.
var sequence = [String]()
while(sequence.count < totalSessions) {
let currentIndex = sequence.count % availableExercises.count
sequence.append(availableExercises[currentIndex])
}
print(sequence)
//["push up", "deep squat", "burpee", "HHSA plank", "push up", "deep squat"]
You can condense your logic by using map(_:) and the remainder operator %:
let sequence = (0..<totalSessions).map {
availableExercises[$0 % availableExercises.count]
}
map(_:) will iterate from 0 up to (but not including) totalSessions, and for each index, the corresponding element in availableExercises will be used in the result, with the remainder operator allowing you to 'wrap around' once you reach the end of availableExercises.
This also has the advantage of preallocating the resultant array (which map(_:) will do for you), preventing it from being needlessly re-allocated upon appending.
Personally, Nirav's solution is probably the best, but I can't help offering this solution, particularly because it demonstrates (pseudo-)infinite lazy sequences in Swift:
Array(
repeatElement(availableExercises, count: .max)
.joined()
.prefix(totalSessions))
If you just want to iterate over this, you of course don't need the Array(), you can leave the whole thing lazy. Wrapping it up in Array() just forces it to evaluate immediately ("strictly") and avoids the crazy BidirectionalSlice<FlattenBidirectionalCollection<Repeated<Array<String>>>> type.

Faster way to create an array of numbers spanning a range in Swift [duplicate]

This question already has answers here:
Is there a way to instantly generate an array filled with a range of values in Swift?
(4 answers)
Closed 6 years ago.
Is there a shorter way to create an array of numbers spanning a range in swift?
Right now, I'm using this:
var arrayOfInts = [UInt32]()
for number in 1...100 {
arrayOfInts.append(number)
}
Is there a one-line way of doing it?
var arrayOfInts = Array(1...100)
Playground Output
Is this short enough?
let array = Array(1...100)
Try like this
var z = [Int](1...100)
print(z)
DEMO

How do I convert Float to Int When Necessary? [duplicate]

This question already has answers here:
Swift - How to remove a decimal from a float if the decimal is equal to 0?
(15 answers)
Closed 6 years ago.
So, I'm pretty new to swift and Xcode and might be missing something obvious, but I've done a bit of research, and can't find my answer.
My code is:
for number in currentList {
listPreview.text = "\(listPreview.text!) \(String(number))"
}
The problem is, the Numbers in currentList are Floats. But if my user were to input a number that isn't a float, it will display as:
"UsersNumber".0
I want it to display as just:
"UsersNumber"
However, if the number the user gave me was a float, say... 1.2, I would still want it to display as 1.2 .
is there some kind of extension that can do this?
Like an if-statement saying
if number.isUselessFloat {
code
}
Thanks in advance,
-Another Nooby user
let number1 = 1.0
let number2 = 1.2
let str = String(format: number1 == floor(number1) ? "%.0f":"%.1f", number1)
print(str)
//prints 1
let str2 = String(format: number2 == floor(number2) ? "%.0f":"%.1f", number2)
print(str2)
//prints 1.2