user3202457
user3202457

Reputation: 145

How to add object in array after every 3 objects in array?

I have an array from 0 to 100.

let array = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"...."100"]

now, I want to add "-" after every 3 objects in an array.

So the output would be like this

array = ["0", "1", "2","-","3", "4", "5","-", "6", "7", "8", "-","9"...."100"]

So, How can I achieve this?

and what if i have model array instead of String array?

   struct SubCategory { 
        var title: String = ""
        var subTitle: String = "" 
  }

  let array = [SubCategory]() 

Upvotes: 1

Views: 1219

Answers (2)

vacawama
vacawama

Reputation: 154671

Here is a way to directly create the result with a single map and a bit of math:

extension Array {
    func adding(_ element: Element, afterEvery n: Int) -> [Element] {
        guard n > 0 else { fatalError("afterEvery value must be greater than 0") }
        let newcount = self.count + self.count / n
        return (0 ..< newcount).map { (i: Int) -> Element in
            (i + 1) % (n + 1) == 0 ? element : self[i - i / (n + 1)]
        }
    }
}

Example:

let result = ["0", "1", "2", "3", "4", "5", "6"].adding("-", afterEvery: 3)
print(result)

Output:

["0", "1", "2", "-", "3", "4", "5", "-", "6"]

Example 2:

This time with [Int]:

let result2 = [1, 2, 3, 4, 5, 6].adding(0, afterEvery: 2)
print(result2)

Output:

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

Example 3:

With a custom struct:

struct SubCategory: CustomStringConvertible {
    var title = ""
    var subTitle = ""

    var description: String { return "SubCategory(title: \(title), subTitle: \(subTitle)" }
}

let array: [SubCategory] = [
    SubCategory(title: "2001", subTitle: "A Space Odyssey"),
    SubCategory(title: "Star Wars Episode 1", subTitle: "The Phantom Menace"),
    SubCategory(title: "Star Wars Episode 2", subTitle: "Attack of the Clones"),
    SubCategory(title: "Star Wars Episode 3", subTitle: "Revenge of the Sith"),
    SubCategory(title: "Star Wars Episode 4", subTitle: "A New Hope"),
    SubCategory(title: "Star Wars Episode 5", subTitle: "The Empire Strikes Back"),
    SubCategory(title: "Star Wars Episode 6", subTitle: "Return of the Jedi")
]

let result3 = array.adding(SubCategory(title: "none", subTitle: "none"), afterEvery: 3)
print(result3)

Output:

[SubCategory(title: 2001, subTitle: A Space Odyssey, SubCategory(title: Star Wars Episode 1, subTitle: The Phantom Menace, SubCategory(title: Star Wars Episode 2, subTitle: Attack of the Clones, SubCategory(title: none, subTitle: none, SubCategory(title: Star Wars Episode 3, subTitle: Revenge of the Sith, SubCategory(title: Star Wars Episode 4, subTitle: A New Hope, SubCategory(title: Star Wars Episode 5, subTitle: The Empire Strikes Back, SubCategory(title: none, subTitle: none, SubCategory(title: Star Wars Episode 6, subTitle: Return of the Jedi]


Mutating version

Here is a version that mutates the original array instead of creating a new one:

extension Array {
    mutating func add(_ element: Element, afterEvery n: Int) {
        guard n > 0 else { fatalError("afterEvery value must be greater than 0") }
        var index = (self.count / n) * n
        while index > 0 {
            self.insert(element, at: index)
            index -= n
        }
    }
}

Example:

var array = ["0", "1", "2", "3", "4", "5", "6"]
array.add("-", afterEvery: 3)
print(array)

Output:

["0", "1", "2", "-", "3", "4", "5", "-", "6"]

Upvotes: 4

Michał Kwiecień
Michał Kwiecień

Reputation: 2874

let array = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]

extension Array {
    func chunks(of size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            let n = Swift.min(size, count - $0)
            return Array(self[$0 ..< $0 + n])
        }
    }
}

let joined = Array(array.chunks(of: 3).joined(separator: ["-"]))

Upvotes: 7

Related Questions