【问题标题】:Extract the elements from array and put back them to another array.?从数组中提取元素并将它们放回另一个数组。?
【发布时间】:2017-05-29 00:04:18
【问题描述】:

假设我有一个包含 10 个元素的数组。说,

var ArrayElemts : ["1","2","3","4","5","6","7","8","9","10","11"]

现在如何将元素从 0 到 5 保留在一个数组集中,将 6 到 10 的元素保留在另一个数组集中?

【问题讨论】:

  • 您的数组样本中有 11 个元素

标签: swift


【解决方案1】:

使用[0...5] 创建ArraySlice,然后使用Array 将其转换回数组:

var arrayElemts = ["1","2","3","4","5","6","7","8","9","10","11"]

let first = Array(arrayElemts[0...5])
let second = Array(arrayElemts[6...10])

print(first)   // ["1", "2", "3", "4", "5", "6"]
print(second)  // ["7", "8", "9", "10", "11"]

【讨论】:

  • 不用说需要array.count检查来避免少于11个元素的数组崩溃
【解决方案2】:

最简单的选择如下:

let partition1 = array.filter { Int($0) ?? 0 <= 5 }
let partition2 = array.filter { Int($0) ?? 0 > 5 }

转换为数字应该是第一步。永远不要把字符串当作数字来处理。

let numbers = array.flatMap { Int($0) }

let partition1 = numbers.filter { $0 <= 5 }
let partition2 = numbers.filter { $0 > 5 }

如果我们假设数组已排序,则有更简单的选择:

let sorted = numbers.sorted()
let partition1: [Int]
let partition2: [Int]

if let partition2start = sorted.index(where: { $0 > 5 }) {
    partition1 = Array(sorted.prefix(upTo: partition2start))
    partition2 = Array(sorted.suffix(from: partition2start))
} else {
    partition1 = sorted
    partition2 = []
}

这是原生的partition 方法可以做到的:

var numbers = array.flatMap { Int($0) }
let index = numbers.partition { $0 > 5 }
let partition1 = Array(numbers.prefix(upTo: index))
let partition2 = Array(numbers.suffix(from: index))

注意该方法更改了原始数组。

【讨论】:

    【解决方案3】:

    将数组分成N 大小的块

    其他答案向您展示了如何使用ArraySlice:s 将原始数组“静态”划分为不同的数组。根据您的描述,通常您可能希望将原始数组分解为 N 大小的块(此处为:n = 5)。

    我们可以使用sequence(state:next) 来实现这样的chunk(bySize:) 方法作为Collection 的扩展:

    extension Collection {
        func chunk(bySize size: IndexDistance) -> [SubSequence] {
            precondition(size > 0, "Chunk size must be a positive integer.")
            return sequence(
                state: (startIndex, index(startIndex, offsetBy: size, limitedBy: endIndex) ?? endIndex),
                next: { indices in
                guard indices.0 != self.endIndex else { return nil }
                indices.1 = self.index(indices.0, offsetBy: size, limitedBy: self.endIndex) ?? self.endIndex
                return (self[indices.0..<indices.1], indices.0 = indices.1).0
            }).map { $0 }
        }
    }
    

    应用于您的示例:

    var arrayElements = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
    let partitions = arrayElements.chunk(bySize: 5)
    /* [["1", "2", "3", "4", "5"],
        ["6", "7", "8", "9", "10"],
        ["11"]] */
    

    chunk(bySize:) 方法会将数组分解为bySize 大小的块,以及(可能)为最终分区的较小块。


    然而,尽管我想尝试使用sequence(state:next) 函数(不需要使用除state 之外的任何可变中间变量),但上面的实现相当臃肿且难以阅读,所以(至于其他许多情况......)我们可能最好只使用while循环:

    extension Collection {
        func chunk(bySize size: IndexDistance) -> [SubSequence] {
            precondition(size > 0, "Chunk size must be a positive integer.")
            var chunks: [SubSequence] = []
            var from = startIndex
            while let to = index(from, offsetBy: size, limitedBy: endIndex) {
                chunks.append(self[from..<to])
                from = to
            }
            if from != endIndex { chunks.append(self[from..<endIndex]) }
            return chunks
        }
    }
    

    【讨论】:

      【解决方案4】:

      lol 我不明白为什么这里有这么复杂的答案 (按原样考虑“数组”变量 -> [Int],而不是 [Any]) 因此,第一种方法仅适用于 Number 类型。 第二个应该这样做

      简单地说:

      let array = [0,1,2,3,4,5,6,7,8,9,10]
      //For instance..
      var arrayA = ["A","B","C","D","E","F","G"]
      
      //First 6 elements
      let arrayOfFirstFour = array.filter({
          return $0 <= 5 ? true : false
      })
      
      //Remaining  elements:
      let restOfArray = array.filter({
          return $0 > 5 ? true : false
      })
      
      let elementsToFourth = arrayA.prefix(upTo: 4)
      let elementsAfterFourth = arrayA.suffix(from: 4)
      print(arrayOfFirstFour)
      print(restOfArray)
      print(elementsToFourth)
      print(elementsAfterFourth)
      
      //[0, 1, 2, 3, 4, 5]
      //[6, 7, 8, 9, 10]
      //["A", "B", "C", "D"]
      //["E", "F", "G"]
      

      【讨论】:

      • 谈论不必要的并发症let arrayOfFirstFour = array.filter{ $0 &lt;= 5 }
      • 如果目的是获取前 n 个元素,只需使用 array.prefix(n)
      • 如果数组是["x", "a", "1", "4", "foo", "11", "3"]怎么办?我相信问题数组中元素的 values 只是示例,而问题涉及根据元素的 positions 拆分元素(而不是 values!),因此您的基于值的过滤器有些误导。 prefixsuffix 方法很好(正如 @Sulthan:s answer 中已经介绍的那样),因为数组将被拆分为正好两个数组(实际上不删除“拆分”元素)。
      • @LeoDabus :也许我有点怀疑,但三元运算符似乎有点像(我知道我在做什么):D
      • 注意prefix(n) 和prefix(upTo: n) 不同
      猜你喜欢
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 2018-12-24
      相关资源
      最近更新 更多