How can i fix the true or false in this code? [duplicate] - swift

This question already has answers here:
Extending Array to check if it is sorted in Swift?
(13 answers)
Closed 3 months ago.
Write a function isIncreasing that takes a list of Ints and returns true if numbers are in increasing (equals OK) order. An empty list should result in true.
func isIncreasing(_ l: [Int]) -> Bool {
var flagreturn=true
if l.count == 0 {
flagreturn=true
} else {
for i: Int in l {
if l[i] < l[i + 1] {
flagreturn=true
}
else{
flagreturn=false
}
}
}
return flagreturn
}
Not sure if I implemented the true and false correctly in the code.

You can zip the sequence with itself dropping the first element and check if it all satisfy a condition like $0 <= $1:
func isIncreasing(_ l: [Int]) -> Bool {
zip(l, l.dropFirst()).allSatisfy { $0 <= $1 }
}
isIncreasing([1,2]) // true
isIncreasing([0,1,1,2]) // true
isIncreasing([0,1,1,2,1]) // false
Expanding on that you can extend sequence constraining its elements to Comparable an d create a generic property like areInIncreasingOrder:
extension Sequence where Element: Comparable {
var areInIncreasingOrder: Bool {
zip(self, dropFirst()).allSatisfy { $0 <= $1 }
}
}
Usage:
[1,2].areInIncreasingOrder // true
[1,2].dropFirst(2).areInIncreasingOrder // true
[0,1,1,2].areInIncreasingOrder // true
[0,1,1,2,1].areInIncreasingOrder // false

Related

How to check if a value in a dictionary has duplicates?

The algorithm below checks to see if an array has at least two or more duplicates. It uses a dictionary to store the occurrences; the time complexity is linear because it has to traverse the dictionary to see if a key occurs twice. In swift, how can I look up a value to see if it occurs more than twice in constant time ?
func containsDuplicate(_ nums: [Int]) -> Bool {
var frequencyTable = [Int:Int]()
for num in nums {
frequencyTable[num] = (frequencyTable[num] ?? 0 ) + 1
}
for value in frequencyTable.values{
if value >= 2 {
return true
}
}
return false
}
containsDuplicate([1,1,2,3,3,3,3,4])
The second loop is not necessary if the first loop checks if the current element has already been inserted before, and returns from the function in that case:
func containsDuplicate(_ nums: [Int]) -> Bool {
var frequencyTable = [Int:Int]()
for num in nums {
if frequencyTable[num] != nil {
return true
}
frequencyTable[num] = 1
}
return false
}
Then it becomes apparent that we don't need a dictionary, a set is sufficient:
func containsDuplicate(_ nums: [Int]) -> Bool {
var seen = Set<Int>()
for num in nums {
if seen.contains(num) {
return true
}
seen.insert(num)
}
return false
}
This can be further simplified: The “insert and check if element was already present” operation can be done in a single call:
func containsDuplicate(_ nums: [Int]) -> Bool {
var seen = Set<Int>()
for num in nums {
if !seen.insert(num).inserted {
return true
}
}
return false
}
This is similar to the solution from this answer
return nums.count != Set(nums).count
but possibly more efficient: The function returns immediately when a duplicate element has been detected.
Finally we can make the function generic, so that it works with all arrays of a hashable type:
func containsDuplicate<T: Hashable>(_ array: [T]) -> Bool {
var seen = Set<T>()
for element in array {
if !seen.insert(element).inserted {
return true
}
}
return false
}
Example:
print(containsDuplicate([1,1,2,3,3,3,3,4])) // true
print(containsDuplicate(["A", "X"])) // false
Or as an extension for arbitrary collections of a hashable type:
extension Collection where Element: Hashable {
func containsDuplicate() -> Bool {
var seen = Set<Element>()
for element in self {
if !seen.insert(element).inserted {
return true
}
}
return false
}
}
print([1,1,2,3,3,3,3,4].containsDuplicate())
print(["A", "X"].containsDuplicate())
You just want to know if it has duplicate, you can use use set and compare the length.
func containsDuplicate(_ nums: [Int]) -> Bool {
return Set(nums).count != nums.count
}
like this examples, because the set remove the duplicate values.

Return value from inner closure

Can't find a solution searching for this. Classic problem - want to find if a sum exists for any pair within an Integer array such that [1,2,3,4], 7 is true
My naive solution give the error
Unexpected non-void return value in void function
I guess because I want to return from the inner forEach closure.
func pairs (_ input: [Int], _ sum: Int ) -> Bool {
input.forEach { (number) in
let secondInput = input.filter{$0 != number}
secondInput.forEach{secondNumber in
if ((secondNumber + number) == sum) {
return true
}
}
}
return false
}
How do I return?
P.S Please ignore if you're only looking to get your naive solution working.
How about this? It takes time + space complexity into consideration.
I believe this should work well for a large set or arrays
func pairs (_ input: [Int], _ sum: Int ) -> Bool {
var firstIndex = 0
var lastIndex = input.count - 1
while firstIndex != lastIndex {
let sumCalculated = input[firstIndex] + input[lastIndex]
if sumCalculated == sum {
return true
} else if sumCalculated > sum {
lastIndex = lastIndex - 1
} else if sumCalculated < sum {
firstIndex = firstIndex + 1
}
}
return false
}
forEach only iterates through the given sequence, you can't return values from a forEach closure. contains is better suited for this kind of tasks:
func pairs(_ input: [Int], _ sum: Int ) -> Bool {
return input.contains { number in
let secondInput = input.filter { $0 != number }
return secondInput.contains { secondNumber in
return secondNumber + number == sum
}
}
}
You could also try a more functional solution, that splits the problem in multiple steps:
func pairs(_ input: [Int], _ sum: Int ) -> Bool {
return input
.flatMap { input1 in input.map { input2 in (input1, input2) } } // build all combinations of numbers from the input array
.contains { input1, input2 in input1 != input2 && input1 + input2 == sum } // check if a pair made of two distinct numbers adds up to the sum
}
If you need a solution that handles any kind of inputs (e.g. only unique numbers), then the functional solution can be adapted to this:
func pairs(_ input: [Int], _ sum: Int ) -> Bool {
return input.indices
.flatMap { i1 in input.indices.map { i2 in (i1, i2) } }
.contains { i1, i2 in i1 != i2 && input[i1] + input[i2] == sum }
}

What is the Swift equivalent of C#/.NET/LINQ's Enumerable.All method?

I want a function that applies a given function to a sequence and returns true iff the given function returns true for every element of the sequence, like Enumerable.All from the C#/.NET/LINQ world.
Building up on Jon's answer: You can use contains()
instead of an (explicit) loop:
extension SequenceType {
func all(#noescape predicate: (Self.Generator.Element) throws -> Bool)
rethrows -> Bool {
return !(try contains { !(try predicate($0)) })
}
}
There isn't a built-in function to do this, but you can easily add your own as a protocol extension method:
extension SequenceType {
func all(#noescape predicate: (Self.Generator.Element) throws -> Bool)
rethrows -> Bool {
for i in self {
if !(try predicate(i)) { return false }
}
return true
}
}
and then use it on a sequence like:
let allPositive = [1, 2, 3].all { $0 > 0 }
Not sure if this helps, but you can achieve the same outcome using reduce. Here's a quick playground I put together to prove the concept:
let nums = [2, 2, 3, 4]
// Will only evaluate to true if all numbers are even.
let allEven = nums.reduce(true) {
if !$0 || $1 % 2 != 0 {
return false
}
return true
}

Defining `Comparable` for optional types in Swift 1.2

import SwiftyJSON
public typealias FeedItem = JSON
extension FeedItem {
var id: Int { get { return self["id"].intValue } }
}
public func <(lhs: FeedItem, rhs: FeedItem) -> Bool {
return lhs.id < rhs.id
}
public func ==(lhs: FeedItem, rhs: FeedItem) -> Bool {
return lhs.id == rhs.id
}
extension FeedItem:Comparable {}
extension Optional : Comparable {}
public func < <T>(l:T?, r:T?) -> Bool {
if let a=l,b=r {
return a < b
} else if (l==nil) && (r != nil) { return true }
else { return false }
}
public func == <T>(l:T?, r:T?) -> Bool {
if let a=l, b=r {
return a==b
} else {
return false
}
}
First, it should read extension Optional<T where T:Comparable>: Comparable but swift 1.2 does not allow that. Anyway I can express the constraint more explicitly rather than expecting the reader to realize the fact by noticing return a < b and return a==b ?
Second (and apparently more important): the code above works when I use < and > but minElement and maxElement both return nil when a nil is present in their input no matter what and min and max fall into infinite recursion:
let items: [FeedItem?] = [ nil, .Some(JSON(["id":2])), .Some(JSON(["id":1])) ]
println(items[0]?.id) // nil
println(items[1]?.id) // Optional(2)
println(items[2]?.id) // Optional(1)
println(items[0] < items[1]) // true
println(items[1] < items[2]) // false
println(items[2] < items[1]) // true
println(minElement(items)) // nil
println(maxElement(items)) // nil
println( min(items[0],items[2]) ) // nil
println( min(items[2],items[1]) ) // crashes due to infinite recursion
I'm no debug (or swift) expert but from what I can gather in XCode I believe the
if let a=l,b=r {
return a < b
}
part somehow misses the point that a and b are not Optionals but FeedItems. I expect the a < b should call the < operator on FeedItem and not the one on Optional but apparently this is exactly what happens; i.e. a < b resolves to the same function it is called from (that is, the < for Optionals) and thus a recursion happens. I might be wrong though.
Insights ?

Swift: return number < 10

That's the code:
import Foundation
func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, condition: lessThanTen)
There is a return true within the if condition and a return false at the end of func hasAnyMatches(). Why is the return false needed?
Without explicitly "telling it" to return something, no function returns false "automatically". I am not writing in swift but I am sure if you take away the return false it'll throw a warning.
The lessThanTen simply returns a bool if the number is smaller than 10.
number < 10 is a statement checking if something is true or false. Hence the return type bool of lessThanTen
You can do like, for such condition.
let LESS_THAN_TEN = 1
let LESS_THAN_HUNDRED = 2
func hasAnyMatch (list: [Int], condition: Int)-> Bool{
var x = false;
switch condition {
case LESS_THAN_TEN :
for a in list {
if a < 10 {
x = true
break
}
}
break
case LESS_THAN_HUNDRED :
for a in list {
if a < 100 {
x = true
break
}
}
break
default:
x = false
}
return x
}
var isLessThanTen = hasAnyMatch([14, 45, 12, 65], condition: LESS_THAN_TEN)
print(isLessThanTen)