【问题标题】:How to reverse array in Swift without using ".reverse()"?如何在不使用“.reverse()”的情况下在 Swift 中反转数组?
【发布时间】:2015-11-01 14:54:47
【问题描述】:

我有数组,需要在没有Array.reverse 方法的情况下反转它,只有for 循环。

var names:[String] = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]

【问题讨论】:

  • 为什么不使用reverse
  • 使用与任何语言相同的基本逻辑,例如C# Reverse an array without using reverse method of array
  • @AlexK。关键是 Swift 标准库中已经有一种有效的方法可以做到这一点。
  • @EricD。是的,但 OP 知道这一点;这可能是一个比较科学的任务
  • 我想要一个以功能方式实现的反向示例,而不改变任何东西,例如类似于传统的 Lisp 递归反向函数。

标签: arrays swift


【解决方案1】:

斯威夫特 3:

var names:[String] = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]

var reversedNames : [String] = Array(names.reversed())

print(reversedNames)  // ["Asus", "Lenovo", "Sony", "Microsoft", "Apple"]

【讨论】:

    【解决方案2】:

    这是@Abhinav 翻译成Swift 2.2的答案:

    var names: [String] = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
    
    var reversedNames = [String]()
    
    for arrayIndex in (names.count - 1).stride(through: 0, by: -1) {
        reversedNames.append(names[arrayIndex])
    }
    

    使用此代码不应给您任何关于使用已弃用的 C 样式 for 循环或使用 -- 的错误或警告。

    Swift 3 - 当前:

    let names: [String] = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
    
    var reversedNames = [String]()
    
    for arrayIndex in stride(from: names.count - 1, through: 0, by: -1) {
        reversedNames.append(names[arrayIndex])
    }
    

    或者,您可以正常循环并每次减去:

    let names = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
    
    let totalIndices = names.count - 1 // We get this value one time instead of once per iteration.
    
    var reversedNames = [String]()
    
    for arrayIndex in 0...totalIndices {
        reversedNames.append(names[totalIndices - arrayIndex])
    }
    

    【讨论】:

    • 没有警告但代码错误。您可以使用for arrayIndex in (names.count - 1).stride(through: 0, by: -1) 避免arradIndex_
    • 谢谢@Sulthan!我已经编辑了我的答案,反映了你更好的解决方案。
    • 顺便说一句,您也可以将它与map 混合成let reversedNames = (names.count - 1).stride(through: 0, by: -1).map { names[$0] }。该解决方案实际上在Eric's answer
    【解决方案3】:

    您真的需要for 循环吗?如果没有,您可以使用reduce

    我想这是在没有 reversed() 方法(Swift 3.0.1)的情况下实现它的最短方法:

    ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"].reduce([],{ [$1] + $0 })
    

    【讨论】:

      【解决方案4】:

      只需要使 (names.count/2) 次通过数组。无需声明临时变量,在进行交换时...它是隐式的。

      var names:[String] = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
      let count = names.count
      for i in 0..<count/2 {
         (names[i],names[count - i - 1])  = (names[count - i - 1],names[i])
      }
      // Yields: ["Asus", "Lenovo", "Sony", "Microsoft", "Apple"]
      

      【讨论】:

        【解决方案5】:
        var names:[String] = [ "A", "B", "C", "D", "E","F","G"]
        var c = names.count - 1
        var i = 0
        while i < c {
            swap(&names[i++],&names[c--])
        }
        

        克里斯蒂克

        while i < c {
           swap(&names[i],&names[c]
           i += 1
           c -= 1
          
        }
        

        【讨论】:

        • 这不再有效,因为前缀和后缀递增/递减运算符不再是 Swift 编程语言的一部分。
        • 被剪断的新代码的行为与原始代码不同,后递增和后递减操作发生在交换之后,而在新代码中它们发生在交换之前。而且我认为这会使代码错过将第一个元素与最后一个元素交换。
        【解决方案6】:

        给你:

        var names:[String] = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
        
        var reversedNames = [String]()
        
        for var arrayIndex = names.count - 1 ; arrayIndex >= 0 ; arrayIndex-- {
            reversedNames.append(names[arrayIndex])
        }
        

        【讨论】:

        • 我收到一条警告说“C 风格的 for 语句已贬值,将来会被删除”:(
        • 这仍然有效吗? @Abhinav
        • @senty 我冒昧地翻译和更新了对 Swift 2.2 的接受答案,以清除 Xcode 中的任何警告。 My Answer.
        • 这不再有效,Swift 已移除对后缀递减运算符的支持。
        【解决方案7】:

        还有stride可以生成反向索引:

        let names = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
        
        var reversed = [String]()
        
        for index in (names.count - 1).stride(to: -1, by: -1) {
            reversed.append(names[index])
        }
        

        它也适用于map

        let reversed = (names.count - 1).stride(to: -1, by: -1).map { names[$0] }
        

        注意:stride 的索引从 1 开始,而不是从 0,这与其他 Swift 序列相反。

        但是,对于将来阅读本文的任何人:使用.reverse() 来实际反转数组,这是预期的方式。

        【讨论】:

        • 我会使用stride(through: 0, by: -1)
        • 致目前正在阅读本文的任何人(5 月 '16,Xcode 7.3,Swift 2.2): .reverse() 创建一个与数组不同的 ReverseRandomAccessCollection>;例如,您不能向其中添加元素。
        • @green_knight 是也不是。是的,默认情况下会这样做。不,这不是问题,因为您可以强制类型为数组,如 let result:[String] = names.reverse() 或使用数组初始值设定项,如 let result = Array(names.reverse())
        • @milos-mandic 你好。您能否下定决心并停止更改已接受的答案?谢谢! ;)
        • @EricD 老实说,我认为你的回答应该被我接受。
        【解决方案8】:

        这是最简单的方法。

        let names:[String] = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
        
        var reversedNames = [String]()
        
        for name in names {
            reversedNames.insert(name, at: 0)
        }
        

        【讨论】:

        【解决方案9】:

        忽略空虚检查..

        var names:[String] = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
        
        var reversedNames = [String]()
        
        for name in names {
            reversedNames.insert((name), at:0)
        }
        
        print(reversedNames)
        

        【讨论】:

          【解决方案10】:

          编辑为通用

          // Swap the first index with the last index.
              // [1, 2, 3, 4, 5] -> pointer on one = array[0] and two = array.count - 1
              // After first swap+loop increase the pointer one and decrease pointer two until
              // conditional is not true. 
              
              func reverse<T>(with array: [T]) -> [T] {
                  var array = array
                  var first = 0
                  var last = array.count - 1
                  while first < last {
                      array.swapAt(first, last)
                      first += 1
                      last -= 1
                  }
                  return array
              }
              
              input-> [1, 2, 3, 4, 5] output ->[5, 4, 3, 2, 1]
              input-> ["a", "b", "c", "d"] output->["d", "c", "b", "a"]
          
            // Or a shorter version divide and conquer
          
              func reversed<T>(with arr: [T]) -> [T] {
                  var arr = arr
                  (0..<arr.count / 2).forEach { i in
                     arr.swapAt(i, arr.count - i - 1)
                  }
                  return arr
               }
          

          【讨论】:

            【解决方案11】:

            你是说

            var names = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
            var newNames = [String]()
            
            for var i = names.count - 1; i >= 0 ; i-- {
              newNames.append(names[i])
            }
            names = newNames
            

            names.map {newNames.insert($0, atIndex: 0)}
            names = newNames
            

            【讨论】:

              【解决方案12】:

              像这样,也许:

              names = names.enumerate().map() { ($0.index, $0.element) }.sort() { $0.0 > $1.0 }.map() { $0.1 }
              

              哦,等等……我使用for循环,对吗?那么大概是这样的:

              for (index, name) in names.enumerate().map({($0.index, $0.element)}).sort({$0.0 > $1.0}).map({$0.1}).enumerate() {
                  names[index] = name
              }
              

              【讨论】:

                【解决方案13】:

                这里是 swift 3 的代码

                let array = ["IOS A", "IOS B", "IOS C"]
                    for item in array.reversed() {
                    print("Found \(item)")
                    }
                

                【讨论】:

                • 关于不使用反向/反向的问题非常具体。甚至在问题下的 cmets 中也提到了它。当 OP 提出这个问题时,每个人 建议使用 reverse/reversed,但 OP 需要别的东西。
                • @Eric Aya:我来这里是为了这个答案。这是一个非常经典的问题,所以我认为应该允许许多不同的方法。
                【解决方案14】:

                这适用于任何大小的数组。

                import Cocoa
                
                var names:[String] = [ "A", "B", "C", "D", "E","F"]
                var c = names.count - 1
                for i in 0...(c/2-1) { swap(&names[i],&names[c-i]) }
                
                print(names)
                

                【讨论】:

                • 如果我没记错的话,swap() 不能在 Swift 2 中与自身交换元素。对于奇数大小的数组,这里会发生这种情况。还是他们在 Swift 2.1 中解决了这个问题?
                • @MartinR 已修复。虽然它会有 1 个项目数组的问题。虽然如果 names.count = 1 你可以跳过整个循环。
                • meh.. 不是一个很好的答案。
                【解决方案15】:

                这是我的做法,Swift 3 没有警告

                let names = ["Apple", "Microsoft", "Sony", "Lenovo", "Asus"]
                var reversedNames = [String]()
                
                for name in names.enumerate() {
                  let newIndex = names.count - 1 - name.index
                  reversedNames.append(names[newIndex])
                }
                

                或者只是简单的

                reversedNames = names.reverse()
                

                【讨论】:

                  【解决方案16】:
                  func reverse(array: inout [String]) {
                      if array.isEmpty { return }
                      var f = array.startIndex
                      var l = array.index(before: array.endIndex)
                      while f < l {
                          swap(array: &array, f, l)
                          array.formIndex(after: &f)
                          array.formIndex(before: &l)
                      }
                  }
                  
                  private func swap( array: inout [String], _ i: Int, _ j: Int) {
                      guard i != j else { return }
                      let tmp = array[i]
                      array[i] = array[j]
                      array[j] = tmp
                  }
                  

                  当然也可以写扩展

                  【讨论】:

                    【解决方案17】:
                    var rArray : [Int] = [2,5,6,8,3,8,9,10]
                    var ReArray = [Int]()
                    var a : Int = 1
                    
                    func reversed (_ array: [Int]) -> [Int] {
                        for i in array {
                            ReArray.append(array[array.count-a])
                            a += 1
                        }
                    
                        rArray = ReArray
                    
                        return rArray
                    }
                    
                    reversed(rArray)
                    
                    print(rArray)
                    

                    【讨论】:

                      【解决方案18】:
                      var arr = [1, 2, 3, 4, 5]   // Array we want to reverse
                      var reverse: [Int]!      // Array where we store reversed values
                      
                      reverse = arr
                      
                      for i in 0...(arr.count - 1) {
                      
                          reverse[i] = arr.last!  // Adding last value of original array at reverse[0]
                          arr.removeLast()        // removing last value & repeating above step.
                      }
                      
                      print("Reverse : \(reverse!)")
                      

                      更简单的方法:)

                      【讨论】:

                        【解决方案19】:

                        斯威夫特 5:

                        让名称:[String] = [“Apple”、“Microsoft”、“Sony”、“Lenovo”、“Asus”]

                        var reversenames: [字符串] = []

                        让 count = names.count

                        对于 0 中的索引..

                        reversenames.insert(names[count-index-1], at: index)
                        

                        }

                        打印(反向名称)

                        【讨论】:

                          【解决方案20】:

                          最近我有一次面试,有人问我这个问题,如何在不使用 reversed() 的情况下反转数组。以下是我的解决方案:

                          func reverseArray( givenArray:inout [Int]) -> [Int] {
                          var reversedArray = [Int]()
                          while givenArray.count > 0 {
                              reversedArray.append(givenArray.removeLast())
                          }
                              return reversedArray
                          }
                          
                          var array = [1,2,3,4,5,6,7]
                          var reversed = reverseArray(givenArray: &array)
                          

                          【讨论】:

                            【解决方案21】:

                            首先,需要找到数组的中间。此方法比线性时间 O(n) 快,比恒定时间 O(1) 复杂度慢。

                            func reverse<T>(items: [T]) -> [T] {
                                var reversed = items
                                let count = items.count
                            
                                let middle = count / 2
                            
                                for i in stride(from: 0, to: middle, by: 1) {
                                    let first = items[i]
                                    let last = items[count - 1 - i]
                                    reversed[i] = last
                                    reversed[count - 1 - i] = first
                                }
                            
                                return reversed
                            }
                            

                            【讨论】:

                              【解决方案22】:

                              这样做是为了反向排序。

                               let unsortedArray: [String] = ["X", "B", "M", "P", "Z"]
                                      // reverse sorting
                                      let reversedArray = unsortedArray.sorted() {$0 > $1}
                              
                                      print(reversedArray) // ["Z", "X", "P", "M", "B"]
                              

                              【讨论】:

                              • 这没有回答问题,因为它对数组进行反向排序,它不会像 OP 要求的那样反转原始顺序。
                              • @Moritz 你是对的,但是有很多新手会在寻找反向排序时找到这个,为了他们,我写了这个解决方案,我已经明确提到“反向排序” .
                              【解决方案23】:

                              我喜欢简单的代码。

                              变量名称:[String] = [“Apple”、“Microsoft”、“Sony”、“Lenovo”、“Asus”]

                              var reversedNames = [""]
                              
                              for name in names {
                                  reversedNames.insert(name, at: 0)
                              }
                              
                              print(reversedNames)
                              

                              【讨论】:

                                【解决方案24】:

                                可以使用swift3文档:

                                let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
                                let reversedNames = names.sorted(by: >)
                                
                                // reversedNames is equal to:
                                //   ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
                                

                                【讨论】:

                                • 这不回答问题,它对数组进行排序,它不会反转它。
                                • 请发布与问题相关的答案。这个答案对数组进行排序而不是反转它。
                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2015-07-09
                                • 2012-04-27
                                • 2020-10-14
                                • 1970-01-01
                                相关资源
                                最近更新 更多