List comprehension in Swift

前端 未结 8 2194
伪装坚强ぢ
伪装坚强ぢ 2020-12-07 13:53

The language guide has revealed no trace of list comprehension. What\'s the neatest way of accomplishing this in Swift? I\'m looking for something similar t

相关标签:
8条回答
  • 2020-12-07 14:48

    With Swift 5, you can choose one of the seven following Playground sample codes in order to solve your problem.


    #1. Using stride(from:to:by:) function

    let sequence = stride(from: 0, to: 10, by: 2)
    let evens = Array(sequence)
    // let evens = sequence.map({ $0 }) // also works
    print(evens) // prints [0, 2, 4, 6, 8]
    

    #2. Using Range filter(_:) method

    let range = 0 ..< 10
    let evens = range.filter({ $0 % 2 == 0 })
    print(evens) // prints [0, 2, 4, 6, 8]
    

    #3. Using Range compactMap(_:) method

    let range = 0 ..< 10
    let evens = range.compactMap({ $0 % 2 == 0 ? $0 : nil })
    print(evens) // prints [0, 2, 4, 6, 8]
    

    #4. Using sequence(first:next:) function

    let unfoldSequence = sequence(first: 0, next: {
        $0 + 2 < 10 ? $0 + 2 : nil
    })
    let evens = Array(unfoldSequence)
    // let evens = unfoldSequence.map({ $0 }) // also works
    print(evens) // prints [0, 2, 4, 6, 8]
    

    #5. Using AnySequence init(_:) initializer

    let anySequence = AnySequence<Int>({ () -> AnyIterator<Int> in
        var value = 0
        return AnyIterator<Int> {
            defer { value += 2 }
            return value < 10 ? value : nil
        }
    })
    let evens = Array(anySequence)
    // let evens = anySequence.map({ $0 }) // also works
    print(evens) // prints [0, 2, 4, 6, 8]
    

    #6. Using for loop with where clause

    var evens = [Int]()
    for value in 0 ..< 10 where value % 2 == 0 {
        evens.append(value)
    }
    print(evens) // prints [0, 2, 4, 6, 8]
    

    #7. Using for loop with if condition

    var evens = [Int]()
    for value in 0 ..< 10 {
        if value % 2 == 0 {
            evens.append(value)
        }
    }
    print(evens) // prints [0, 2, 4, 6, 8]
    
    0 讨论(0)
  • 2020-12-07 14:50

    One aspect of list comprehension that hasn't been mentioned in this thread is the fact that you can apply it to multiple lists' Cartesian product. Example in Python:

    [x + y for x in range(1,6) for y in range(3, 6) if x % 2 == 0]
    

    … or Haskell:

    [x+y | x <- [1..5], y <- [3..5], x `mod` 2 == 0]
    

    In Swift, the 2-list equivalent logic is

    list0
        .map { e0 in
            list1.map { e1 in
                (e0, e1)
            }
        }
    .joined()
    .filter(f)
    .map(g)
    

    And we'd have to increase the nesting level as the number of lists in input increases.

    I recently made a small library to solve this problem (if you consider it a problem). Following my first example, with the library we get

    Array(1...5, 3...5, where: { n, _ in n % 2 == 0}) { $0 + $1 }
    

    The rationale (and more about list comprehension in general) is explained in an blog post.

    0 讨论(0)
提交回复
热议问题