0

I have code like below

let myNums = getXYZ(nums: [1,2,3,4,5])

func getXYZ(nums: [Int]) -> [Int] {
let newNum = nums.map { (num) -> Int in

    if num == 2 {
    //do something and continue execution with next element in list like break/fallthrough
        return 0
    }
    return num
}

return newNum

}

print(myNums)`

This prints [1,0,3,4,5]

but i want the output to be [1,3,4,5]. How can I exclude 2? I want to alter the if statement used so as to not include in array when it sees number 2

I have to use .map here but to exclude 2..is there any possibility

Please let me know

5
  • 4
    use compactMap and return nil when num == 2 Commented Feb 11, 2019 at 2:01
  • it says " nil is incompatible with return type 'Int'" Commented Feb 11, 2019 at 2:07
  • try koropok's suggestion with flatMap Commented Feb 11, 2019 at 2:08
  • flatMap is depraced also it returns same error even with flatMap " nil is incompatible with return type 'Int'". I tried if num == 2 { return nil } Commented Feb 11, 2019 at 2:12
  • Like what koropok said use compactMap and inside your closure make your return type nullable like so (num) -> Int? Commented Feb 11, 2019 at 2:17

5 Answers 5

1

I'd simply do a filter as described as your problem, you want to filter the numbers by removing another number.

var myNums = [1, 2, 3, 4, 5]
let excludeNums = [2]

let newNum = myNums.filter({ !excludeNums.contains($0) })

print(newNum) //1, 3, 4, 5

If you need to do a map, you could do a map first then filter.

let newNum = myNums.map({ $0*2 }).filter({ !excludeNums.contains($0) })
print(newNum) //4, 6, 8, 10

This maps to multiplying both by 2 and then filtering by removing the new 2 from the list. If you wanted to remove the initial 2 you would have to filter first then map. Since both return a [Int] you can call the operations in any order, as you deem necessary.

Sign up to request clarification or add additional context in comments.

Comments

1

As suggested by @koropok, I had to make below changes

nums.compactMap { (num) -> Int? in .... if num == 2 { return nil }

1 Comment

you can just use Shorthand Argument Names for inline closures. remove (num) -> int? and replace num == 2 with $0 == 2.
1

I suggest you to use filter instead of map:

let myNums = [1,2,3,4,5]
let result1 = myNums.filter{ return $0 != 2 }
print(result1) // This will print [1,3,4,5]

If you must definitely use map, then use compactMap:

let result2 = myNums.compactMap { return $0 == 2 ? nil : $0 }
print(result2) // This will print [1,3,4,5]

Hope this helps

1 Comment

You can shorten the compactMap version by getting rid of the return (in Swift 5, at least).
1

filter is more appropriate than map for your use case.

If you want to exclude only 1 number:

func getXYZ(nums: [Int]) -> [Int] {
    return nums.filter { $0 != 2 }
}

If you want to exclude a list of numbers, store those exclusions in a Set since Set.contains runs in O(1) time, whereas Array.contains runs in O(n) time.

func getXYZ(nums: [Int]) -> [Int] {
    let excluded: Set<Int> = [2,4]
    return nums.filter { !excluded.contains($0) }
}

Comments

0

My solution is based on enumerated() method:

let elements = nums.enumerated().compactMap { (index, value) in
                    ( index == 0 ) ? nil : value
                }

enumerated() add element's index as first closure argument

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.