Milos Mandic
Milos Mandic

Reputation: 1071

How to reverse array in Swift without using ".reverse()"?

I have array and need to reverse it without Array.reverse method, only with a for loop.

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

Upvotes: 28

Views: 65484

Answers (27)

Habibur Rahman
Habibur Rahman

Reputation: 319

Reverse the array recursively.

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

func reverseRecursively<T>(start: Int, end: Int, array: inout [T]) {
    if start > end { return }
    
    let temp = array[start]
    array[start] = array[end]
    array[end] = temp

    reverseRecursively(start: start + 1, end: end - 1, array: &array)
}

reverseRecursively(start: 0, end: name.count - 1, array: &names)

print(names)
// output: "["Asus", "Lenovo", "Sony", "Microsoft", "Apple"]"

Upvotes: 0

Pushker pandey
Pushker pandey

Reputation: 7

There are so many answers, Here in swift 5 by using generic method to reverse any type of array: modified from @tomeriko 's solution

func reverseArray<Element:Equatable>(input : [Element])-> [Element]{
   var count = input.count
   var result_ = input
   for index in 0..<input.count{
      result_.insert(input[count-index-1], at: index)
      result_.removeLast()
    }
   return result_
 }
 print(reverseArray(input: [1,2,3,4,5,6]))
 print(reverseArray(input: ["1","2","3","4"]))

output:

[6, 5, 4, 3, 2, 1]

["4", "3", "2", "1"]

Upvotes: 0

Saikiran Komirishetty
Saikiran Komirishetty

Reputation: 6565

Swift 5:

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

var reversenames: [String] = []

let count = names.count

for index in 0..<count {
    reversenames.insert(names[count-index-1], at: index)
}

print(reversenames)

Upvotes: 3

vadian
vadian

Reputation: 285072

The most efficient way is to swap the items at start- and endIndex and move the indices bidirectional to the middle. This is a generic version

extension Array {
     mutating func upsideDown() {
        if isEmpty { return }
        var 👉 = startIndex
        var 👈 = index(before: endIndex)
        while 👉 < 👈 {
            swapAt(👉, 👈)
            formIndex(after: &👉)
            formIndex(before: &👈)
        }
    }
}

Upvotes: 2

Obyadur
Obyadur

Reputation: 34

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

// 'while' loop   
var index = 0
let totalIndices = names.count - 1
while index < names.count / 2 {
    names.swapAt(index, totalIndices-index)
    index += 1
}
 
// 'for' loop
for index in 0..<names.count/2 {
    names.swapAt(index, names.count-index-1)
}

// output: "["Asus", "Lenovo", "Sony", "Microsoft", "Apple"]"

Upvotes: -1

Kuvonchbek Yakubov
Kuvonchbek Yakubov

Reputation: 749

First, need to find the middle of array. This method is faster than the linear time O(n) and slower than the constant time O(1) complexity.

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
}

Upvotes: 0

M A Russel
M A Russel

Reputation: 1557

Recently I had an interview and I was asked this question, how to reverse an array without using reversed(). Here is my solution below:

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)

Upvotes: 0

user3441734
user3441734

Reputation: 17544

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--])
}

Cristik

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

Upvotes: 4

Israel Manzo
Israel Manzo

Reputation: 237

Edited as generic

// 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
     }

Upvotes: 2

Pilkie
Pilkie

Reputation: 31

Ignoring checks for emptiness..

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

var reversedNames = [String]()

for name in names {
    reversedNames.insert((name), at:0)
}

print(reversedNames)

Upvotes: 3

Mayank Neema
Mayank Neema

Reputation: 1

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!)")

A more simple way :)

Upvotes: 0

Dre Adesina
Dre Adesina

Reputation: 21

I like simple codes.

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

var reversedNames = [""]

for name in names {
    reversedNames.insert(name, at: 0)
}

print(reversedNames)

Upvotes: -2

brunobasas
brunobasas

Reputation: 383

Do you really need a for loop? If not, you can use reduce.

I guess that this is the shortest way to achieve it without reversed() method (Swift 3.0.1):

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

Upvotes: 18

ZGski
ZGski

Reputation: 2538

Here is @Abhinav 's answer translated to 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])
}

Using this code shouldn't give you any errors or warnings about the use deprecated of C-style for-loops or the use of --.

Swift 3 - Current:

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])
}

Alternatively, you could loop through normally and subtract each time:

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])
}

Upvotes: 23

Muhammad Khan
Muhammad Khan

Reputation: 322

Here is the most simpler way.

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

var reversedNames = [String]()

for name in names {
    reversedNames.insert(name, at: 0)
}

Upvotes: 1

Divyanshu Kumar
Divyanshu Kumar

Reputation: 1461

Do it like this for reversed sorting.

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

        print(reversedArray) // ["Z", "X", "P", "M", "B"]

Upvotes: -1

Paresh Hirpara
Paresh Hirpara

Reputation: 487

You can use the swift3 document:

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

// reversedNames is equal to:
//   ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

Upvotes: -2

md.rayhan_bhuiyan
md.rayhan_bhuiyan

Reputation: 1

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)

Upvotes: 0

Aleksey Kornienko
Aleksey Kornienko

Reputation: 312

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
}

Or you can write extension of course

Upvotes: 0

SpaceX
SpaceX

Reputation: 2890

Swift 3:

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

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

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

Upvotes: 30

Inder_iOS
Inder_iOS

Reputation: 1656

Here the code for swift 3

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

Upvotes: -1

Pavle Mijatovic
Pavle Mijatovic

Reputation: 783

Here is how I did it and there is no warning for 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])
}

or just simply

reversedNames = names.reverse()

Upvotes: 0

Mike Chirico
Mike Chirico

Reputation: 3491

Only need to make (names.count/2) passes through the array. No need to declare temporary variable, when doing the swap...it's implicit.

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"]

Upvotes: 6

Simon O&#39;Doherty
Simon O&#39;Doherty

Reputation: 9359

This will work with any sized array.

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)

Upvotes: 0

Eric Aya
Eric Aya

Reputation: 70098

There's also stride to generate a reversed index:

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])
}

It also works well with map:

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

Note: stride starts its index at 1, not at 0, contrary to other Swift sequences.

However, to anyone reading this in the future: use .reverse() instead to actually reverse an array, it's the intended way.

Upvotes: 4

Abhinav
Abhinav

Reputation: 38162

Here you go:

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

var reversedNames = [String]()

for var arrayIndex = names.count - 1 ; arrayIndex >= 0 ; arrayIndex-- {
    reversedNames.append(names[arrayIndex])
}

Upvotes: 3

0x416e746f6e
0x416e746f6e

Reputation: 10136

Like this, maybe:

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

Oh, wait.. I have to use for loop, right? Then like this probably:

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

Upvotes: 1

Related Questions