【问题标题】:Using "Map" in Swift To Create Superset of Two Arrays在 Swift 中使用“Map”创建两个数组的超集
【发布时间】:2016-09-28 16:04:13
【问题描述】:

假设我有两个数组:

let letterArray = ["a", "b", "c", "d", "e"...]
let numberArray = [1, 2, 3, 4, 5, 6, 7...]

我想组合这两个数组,这样我就可以得到一个输出

["a1", "b2", "c3", "d4", "e5"]

我该怎么做呢?

【问题讨论】:

  • 'Superset' 类似于:["a", "b", ..., 1, 2, ... ]

标签: ios arrays swift xcode


【解决方案1】:

您可以在地图前使用zip(_:_:)

let a = ["a", "b", "c", "d", "e"]
let b = [1, 2, 3, 4, 5]

let result = zip(a, b).map { $0 + String($1) }

print(result) // => ["a1", "b2", "c3", "d4", "e5"]

You can try this code here.

zip(_:_:) 生成一个自定义的Zip2Sequence,它具有SequenceType 协议的特殊实现,以便它迭代由两个源集合组成的对。

【讨论】:

    【解决方案2】:

    实际上你可以只使用map

    如果两个序列的大小相同,只是enumeratemap

    let result = letterArray.enumerate().map { $0.element + String(numberArray[$0.index]) }
    

    如果您不确定哪个较大,并且您想使用较小的进行修剪,只需 flatMap 将不需要的值去掉:

    let result = letterArray.enumerate().flatMap {
        guard numberArray.count > $0.index else { return .None }
        return $0.element + String(numberArray[$0.index])
    } as [String]
    

    【讨论】:

    • 如果你还是要对它进行平面映射,你可以在第一遍就这样做。 let result: [String] = letterArray.enumerate().flatMap { guard numberArray.count > $0.index else { return .None } return $0.element + String(numberArray[$0.index]) }
    • 我会避免这种情况,乍一看还不清楚,而且速度要慢一倍
    • @AMomchilov 我不会争论清晰度部分。我也不会使用它(我认为 zip + map 更具可读性),但我只是想展示它是否可以只使用 map。
    • 啊,是的,我承认了。这是一个聪明的方法:p。您也可以直接映射整数:[0..<letterArray.count].map{ letterArray[$0] + numberArray[$0] }
    【解决方案3】:

    #1。使用zip(_:_:)String 数组的元素与Int 数组的元素组合成String 的新数组

    在 Swift 3 中,Swift 标准库提供了zip(_:_:) 函数。 zip(_:_:) 有以下声明:

    func zip<Sequence1, Sequence2>(_ sequence1: Sequence1, _ sequence2: Sequence2) -> Zip2Sequence<Sequence1, Sequence2> where Sequence1 : Sequence, Sequence2 : Sequence
    

    创建由两个底层序列构成的对序列。


    为了从Zip2Sequence 实例中获取新数组,您可以使用Zip2Sequencemap(_:) 方法。下面使用 map(_:) 的 Playground 代码将您的字母和数字元素组合成一个新的 String 数组:

    let letterArray = ["a", "b", "c", "d", "e"]
    let numberArray = [1, 2, 3, 4, 5, 6, 7]
    
    let zipSequence = zip(letterArray, numberArray)
    let finalArray = zipSequence.map({ (tuple: (letter: String, number: Int)) -> String in
        return tuple.letter + String(tuple.number)
    })
    
    print(finalArray) // prints ["a1", "b2", "c3", "d4", "e5"]
    

    你可以用更简洁的风格重构之前的代码:

    let letterArray = ["a", "b", "c", "d", "e"]
    let numberArray = [1, 2, 3, 4, 5, 6, 7]
    
    let finalArray = zip(letterArray, numberArray).map { $0.0 + String($0.1) }
    
    print(finalArray) // prints ["a1", "b2", "c3", "d4", "e5"]
    

    作为map(_:) 的替代方案,您可以使用Zip2Sequencereduce(_:_:) 方法:

    let letterArray = ["a", "b", "c", "d", "e"]
    let numberArray = [1, 2, 3, 4, 5, 6, 7]
    
    let zipSequence = zip(letterArray, numberArray)
    let finalArray = zipSequence.reduce([]) { (partialResult: [String], tuple: (letter: String, number: Int)) -> [String] in
        return partialResult + [tuple.letter + String(tuple.number)]
    }
    
    print(finalArray) // prints ["a1", "b2", "c3", "d4", "e5"]
    

    #2。使用Array扩展自定义方法将String数组的元素与Int数组的元素组合成String的新数组

    如果您不想使用zip(_:_:),您可以创建自己的Array 扩展方法以获得预期的结果。下面的 Playground 代码显示了如何创建它:

    extension Array where Element == String {
    
        func mergeLettersWithNumbers(from numberArray: [Int]) -> [String] {
            var index = startIndex
            let iterator: AnyIterator<String> = AnyIterator {
                defer { index = self.index(index, offsetBy: 1) }
                guard index < self.endIndex, index < numberArray.endIndex else { return nil }
                return self[index] + String(numberArray[index])
            }
            return Array(iterator)
        }
    
    }
    
    let letterArray = ["a", "b", "c", "d", "e"]
    let numberArray = [1, 2, 3, 4, 5, 6, 7]
    
    let newArray = letterArray.mergeLettersWithNumbers(from: numberArray)
    print(newArray) // prints ["a1", "b2", "c3", "d4", "e5"]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多