如何在Swift中将多个数组合并为一个具有交替值的数组?

时间:2017-04-28 13:35:53

标签: swift

如何将多个数组合并为一个具有交替值的数组?

例如:

var arr1 = [1, 2, 3, 4, 5]
var arr2 = [a, b, c, d, e, f, g]
var arr3 = [aa, bb, cc, dd]

[1, a, aa, 2, b, bb, 3, c, cc, 4, d, dd, 5, e, f, g]

6 个答案:

答案 0 :(得分:1)

我为你做了一个功能。您可以使用几个不同的数组作为参数

var arr1 = [1, 2, 3, 4, 5]
var arr2 = ["a", "b", "c", "d", "e", "f", "g"]
var arr3 = ["aa", "bb", "cc", "dd"]

func combine<T>(arrays:[[T]]) -> [T] {

    let maxCount = arrays.reduce(0) { max($0, $1.count) }

    var result = [T]()

    for i in 0..<maxCount {
        for array in arrays {
            if i < array.count {
                result.append(array[i])
            }
        }
    }

    return result

}

combine(arrays: [arr1,arr2,arr3] as [[Any]])
// or
combine(arrays: [arr2,arr3]) // if type is the same

答案 1 :(得分:1)

如果3个数组中的元素类型相同,则可以计算最大大小并使用flatMap合并它们。

例如:

var arr1 = ["1", "2", "3", "4", "5"]
var arr2 = ["a", "b", "c", "d", "e", "f", "g"]
var arr3 = ["aa", "bb", "cc", "dd","ee"]

let arrays    = [arr1,arr2,arr3]
let merged    = (0..<arrays.map{$0.count}.max()!)
               .flatMap{i in arrays.filter{i<$0.count}.map{$0[i]} }

[编辑]或者如果您想为给定类型的任意数量的数组提供更通用的解决方案,您可以创建一个函数来执行此操作:

func mergeArrays<T>(_ arrays:[T] ...) -> [T]
{ 
  return (0..<arrays.map{$0.count}.max()!)
         .flatMap{i in arrays.filter{i<$0.count}.map{$0[i]} }
}  

let merged = mergeArrays(arr1,arr2,arr3)            

[EDIT2]删除了zip的使用,简化了表达式。

保持拉链接近以供将来参考:

func mergeArrays<T>(_ arrays:[T] ...) -> [T]
{ 
   return arrays.reduce([[T]]())
   { zip($0,$1).map{$0+[$1]} + $0.dropFirst($1.count) + $1.dropFirst($0.count).map{[$0]} }
   .flatMap{$0}
}    

它可能会更快一些。我没有测量过它

答案 2 :(得分:0)

我认为没有通用功能,但实现它非常简单:

    var sumArr: [Any] = []
    let max_count = max(arr1.count, arr2.count, arr3.count)
    for i in 0...max_count {
        if arr1.count > i { sumArr.append(arr1[i]) }
        if arr2.count > i { sumArr.append(arr2[i]) }
        if arr3.count > i { sumArr.append(arr3[i]) }
     }

或者让它更可重复使用:

    func combineArrays(arrays: [[Any]]) -> [Any] {
        var sumArr: [Any] = []
        guard let max_count = arrays.map({$0.count}).max() else { return [] }
        for i in 0...max_count {
            for arr in arrays {
                if arr.count > i { sumArr.append(arr[i]) }
            }
        }
        return sumArr
    }

答案 3 :(得分:0)

你可以试试这个

var c = 0
var i = 0
var arr1 = [1, 2, 3, 4, 5]
var arr2 = [a, b, c, d, e, f, g]
var arr3 = [aa, bb, cc, dd]
var arr = [] 
while (c < 3) {
    if i < arr1.count {
        arr.append(arr1[i])
    } else {
        c += 1
    }
    if i < arr2.count {
        arr.append(arr2[i])
    } else {
        c += 1
    }
    if i < arr3.count {
        arr.append(arr3[i])
    } else {
        c += 1
    }
    i += 1
}

答案 4 :(得分:0)

试试这个:

extension Array {

    //Mutating
    mutating func weave(with array: Array) -> Array {
        precondition(!isEmpty && !array.isEmpty)
        var weavedArray = Array<Element>()
        weavedArray.reserveCapacity(count + array.count)
        var inputArray = array
        for _ in 0..<[count, array.count].min()! {
            weavedArray.append(self.removeFirst())
            weavedArray.append(inputArray.removeFirst())
        }
        let largerArr = largerOf(self, inputArray)
        if largerArr.count != 0 {
            weavedArray.append(contentsOf: largerArr)
        }
        self = weavedArray
        return weavedArray
    }

    //Non-mutating
    func weaved(with array: Array) -> Array {
        precondition(!isEmpty && !array.isEmpty)
        var weavedArray = Array<Element>()
        weavedArray.reserveCapacity(count + array.count)
        var selfArray = self
        var inputArray = array
        for _ in 0..<[count, array.count].min()! {
            weavedArray.append(selfArray.removeFirst())
            weavedArray.append(inputArray.removeFirst())
        }
        let largerArr = largerOf(selfArray, inputArray)
        if largerArr.count != 0 {
            weavedArray.append(contentsOf: largerArr)
        }
        return weavedArray
    }

    internal func largerOf<T>(_ arr1: Array<T>, _ arr2: Array<T>) -> Array<T> {
        switch (arr1.count, arr2.count) {
        case (let a, let b) where a > b: return arr1
        case (let a, let b) where a < b: return arr2
        case (let a, let b) where a == b: return arr1
        default: return arr2
        }
    }
}

用法

变异 - .weave(with: )

let odds = [1, 3, 5, 7, 9]
let evens = [2, 4, 6, 8, 10]

odds.weave(with: evens)

print(odds) //prints: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(evens) //prints: [2, 4, 6, 8, 10]

非变异 - .weaved(with: )

let odds = [1, 3, 5, 7, 9]
let evens = [2, 4, 6, 8, 10]

let firstTen = odds.weaved(with: evens)

print(firstTen) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(odds) //prints: [1, 3, 5, 7, 9]
priny(evens) //prints: [2, 4, 6, 8, 10]

希望这有帮助,如果您有任何其他问题,请随时提出!

答案 5 :(得分:0)

这是我为您提供的解决方案:

const arr1 = [1, 2, 3, 4, 5]
const arr2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
const arr3 = ['aa', 'bb', 'cc', 'dd']

const displayAlternatedValues = (a, b, c) => {
  const allArraysInOne = [a, b, c]
  let arrayOfLengths = []
  let arrayOfAlternatedValues = []

  for (let i = 0; i < allArraysInOne.length; i++) {
    const findMaxLength = arrayOfLengths.push(allArraysInOne[i].length)
  } 

  const maxLength = Math.max(... arrayOfLengths)
  // this function allows us to find the length of iteration for the next 'for'

  for (let i = 0; i < maxLength; i++) {
    const associateAlternedValues = [a[i], b[i], c[i]]
    const pushAlternedValues = arrayOfAlternatedValues.push(...associateAlternedValues)
  }
  // this function allows us to create a new array with values sorted by their index

  const cleanedAlternedValues = arrayOfAlternatedValues.filter(elem => typeof elem !=='undefined')

  // this variable create a clean array, without displaying 'undefined' in case there 
  // is no value matching a[i], b[i], c[i]

  return cleanedAlternedValues

}

displayAlternatedValues(arr1, arr2, arr3)

// result : [ 1, 'a', 'aa', 2, 'b', 'bb', 3, 'c', 'cc', 4, 'd', 'dd', 5, 'e', 'f', 'g' ]

希望这会有所帮助!我还在学习 !