Swift: алгоритм добавления элементов в массив - PullRequest
0 голосов
/ 10 марта 2019

Мне нужно добавить элементы в массив, используя определенный алгоритм:

с начальным индексом == 2 и разделителем == 5

например, входной массив:

["1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"]

например, выходной массив:

["1", "1", "X", "1", "1", "1", "1", "1", "X", "1", "1", "1", "1", "1", "X", "1", "1", "1", "1"]

вот мой код, но я не могу найти способ заставить его работать должным образом, ожидая некоторой помощи

var mixStartIndex = 2
var mixSeparator = 5

let array = ["1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"]
var result = [AnyObject]()
for (index, item) in array.enumerated() {
    if (index > mixStartIndex+mixSeparator && index % mixSeparator == 0) || index == mixStartIndex {
        result.append("X" as AnyObject)
    }
    result.append(item as AnyObject)
}
print(result)

PS Я работаю с объектами, только что сделал пример со строками для простоты

Ответы [ 4 ]

0 голосов
/ 10 марта 2019

Вот еще один, немного более простой.

  let array = ["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"]

  let result = array.enumerated().flatMap{ ($0.offset - 1)  % 5 == 0 ? [$0.element, "X"] : [$0.element]}

  print(result)
0 голосов
/ 10 марта 2019

Функциональное решение для создания массива, в котором элементы вставлены в результирующий массив:

let result: [String] = array.enumerated().reduce(into:[]) { acc, elm in
    let tempo = ((elm.offset - 2) % 5 == 0 ? ["X"] : []) + [elm.element]
    acc.append(contentsOf: tempo)
}

Если вместо вставки вы хотите заменить элементы:

let result = array.enumerated().map {
    ($0.offset - 2) % 6 == 0 ? "X" : $0.element
}

Array.insert (_: at:)

Мы могли бы использовать встроенную функцию Array.insert(_:at:)

let newCount = array.count > 2 ? array.count + 1 + (array.count - 3) / 6 : array.count

var index = 2
let mixSeparator = 6

var result = array

while index < newCount {
    result.insert("X", at: index)
    index += mixSeparator
}

Но это было бы неэффективно не только потому, что вы весь массив затем начинаете вставлять, но и потому, что insert(_:at:) является операцией O (n).Это означает, что все элементы после индекса вставки должны быть сдвинуты.Более эффективным решением было бы сделать вставку итеративно:


Итеративная вставка

Вот довольно простое для понимания итеративное решение:

let array = ["1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"]

var result = array
let x = "X"

let startIndex = 2
let step = 6

var count = 0
var index = 2

while index < array.count {
    result[index] = x
    count += 1
    index += step
}

result.append(contentsOf: Array(repeating: "1", count: count))

Или,если вы хотите создать массив result за один раз:

let newCount = array.count > 2 ? array.count + 1 + (array.count - 3) / 6 : array.count

var result = [String]()
result.reserveCapacity(newCount)

let startIndex = 2
let step = 6

var nextIndexToPutX = startIndex
var index = 0

while index < newCount {
    if index == nextIndexToPutX {
        result.append("X")
        nextIndexToPutX += step
    } else {
        result.append("1")
    }
    index += 1
}

Заменяйте итеративно

var result = [String]()
result.reserveCapacity(array.count)

var nextIndexToPutX = 2
let step = 6

var index = 0

while index < array.count {
    if index == nextIndexToPutX {
        result.append("X")
        nextIndexToPutX += step
    } else {
        result.append(array[index])
    }
    index += 1
}
0 голосов
/ 10 марта 2019

Это работает и проще принятого ответа:

extension Array {
    func example(start: Index, seperator: Index, insert: Element) -> [Element] {
        var result = self
        var index = start
        while index < result.count {
            result.insert(insert, at: index)
            index += seperator + 1
        }
        return result
    }

    // a functional solution
    func example2(start: Index, seperator: Index, insert: Element) -> [Element] {
        return self.enumerated().flatMap { offset, element in
            offset == start || offset > start && (offset - start) % seperator == 0 ? [insert, element] : [element]
        }
    }
}

print(array.example(start: mixStartIndex, seperator: mixSeparator, insert: "X"))
print(array.example2(start: mixStartIndex, seperator: mixSeparator, insert: "X"))
0 голосов
/ 10 марта 2019

Вам не хватает, чтобы добавить входной массив как часть выходного массива

Попробуйте добавить это

else
        {
            result.append(array[index])
        }

enter image description here

Обновление: изменение условия на if (((index-mixStartIndex)%mixSeparator)==0 || index == mixStartIndex) работает для пятого индекса

var mixStartIndex = 2
var mixSeparator = 6

func mix(array: [String]) -> [String] {
    guard !array.isEmpty else { return array }
    var result = [String]()
    for (index, _) in array.enumerated() {
        if (((index-mixStartIndex)%mixSeparator)==0 || index == mixStartIndex) {
            result.append("X")
     }
        else
        {
            result.append(array[index])
        }
}
    return result
}

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...