Подтвердить что ты не робот

Как можно быстро сгладить массив в Swift?

Я хочу включить это:

let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

в это:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

очень изящно.

Самый простой способ, конечно,

var y = [Int]()
x.forEach { y.appendContentsOf($0) }

Но это делает результирующий массив изменчивым, что необязательно. Мне это не нравится.

Я попытался использовать reduce:

let y = x.reduce([Int]()) { (array, ints) -> [Int] in
    array.appendContentsOf(ints)
    return array
}

Но компилятор жалуется, что array является неизменным, поэтому я не могу вызвать метод мутации appendContentsOf.

Следовательно, я добавил некоторые вещи:

let y = x.reduce([Int]()) { (array, ints) -> [Int] in
    var newArr = array
    newArr.appendContentsOf(ints)
    return newArr
}

Это просто плохо. У меня есть инстинкт о том, что это не экономно.

Как я могу сгладить массив более быстро, чем описанные выше методы? Один лайнер был бы хорош.

4b9b3361

Ответ 1

Здесь есть встроенная функция joined:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]].joined()

(Обратите внимание, что это фактически не возвращает другой массив, он возвращает FlattenBidirectionalCollection, но это обычно не имеет значения, поскольку это еще последовательность, которую вы можете использовать с циклами for и еще что-то., вы можете использовать Array(arrayOfArrays.joined()).)


Функция flatMap также может помочь вам. Его подпись, грубо говоря,

flatMap<S: SequenceType>(fn: (Generator.Element) -> S) -> [S.Generator.Element]

Это означает, что вы можете передать fn, который для любого элемента возвращает последовательность, и он будет объединять/объединять эти последовательности.

Так как ваши элементы массива сами являются последовательностями, вы можете использовать функцию, которая просто возвращает сам элемент ({ x in return x } или эквивалентно просто {$0}):

[[1, 2, 3], [4, 5, 6], [7, 8, 9]].flatMap{ $0 }

Ответ 2

В Swift 5 вы можете выбрать один из трех следующих способов, чтобы сгладить массив.


# 1. Свести массив с flatMap(_:) метода Array flatMap(_:)

В Swift типы, соответствующие протоколу Sequence (включая Array), имеют flatMap(_:). Array flatMap(_:) имеет следующее объявление:

func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence

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

Пример кода Playground ниже показывает, как сгладить Array типа [[Int]] для типа [Int] используя flatMap(_:):

let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.flatMap({ (element: [Int]) -> [Int] in
    return element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 2. Свести массив с помощью метода Array joined()

Array есть метод joined(). joined() имеет следующее объявление:

func joined() -> FlattenSequence<Array<Element>>

Возвращает элементы этой последовательности последовательностей, сцепленные.

В следующем примере кода Playground показано, как сгладить Array типа [[Int]] для типа [Int] с помощью joined():

let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenCollection = array.joined()
let flattenArray = Array(flattenCollection)
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 3. Выровнять массив с помощью метода reduce(_:_:) Array reduce(_:_:)

Swift Array имеет метод reduce(_:_:) со следующим объявлением:

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result

Возвращает результат объединения элементов последовательности с использованием данного замыкания.

В следующем примере кода Playground показано, как сгладить Array типа [[Int]] чтобы ввести [Int] используя reduce(_:_:):

let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.reduce([], { (result: [Int], element: [Int]) -> [Int] in
    return result + element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]

В качестве альтернативы reduce(_:_:), вы можете использовать reduce(into:_:):

let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.reduce(into: [Int]()) { (result: inout [Int], element: [Int]) in
    result += element
}
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]

Ответ 3

Функция сглаживания в массиве:

let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let y = Array(x.flatten())
print(y)

функция flatMap в массиве:

let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let y = x.flatMap({$0})
print(y)

Ваш результат:

введите описание изображения здесь

Подробнее: Массив в Swift