Как объединить 2 массива с параллельными индексами в Swift [дубликат]

Это в основном делает то, что делает @ Bass33, за исключением того, что я также даю возможность использовать отрицательный индекс для подсчета с конца.

// use a negative index to insert relative to the end of the string.

String.prototype.insert = function (index, string) {
  var ind = index < 0 ? this.length + index  :  index;
  return  this.substring(0, ind) + string + this.substring(ind, this.length);
};

Use case: Предположим, вы имеете полноразмерные изображения, используя соглашение об именах, но не можете обновлять данные, чтобы также предоставлять эскизы эскизов.

var url = '/images/myimage.jpg';
var thumb = url.insert(-4, '_thm');

//    result:  '/images/myimage_thm.jpg'
6
задан Dan Beaulieu 22 January 2016 в 17:59
поделиться

2 ответа

Если оба массива имеют ту же длину , то это возможное решение:

let one = [1,3,5]
let two = [2,4,6]

let merged = zip(one, two).flatMap { [$0, $1] }

print(merged) // [1, 2, 3, 4, 5, 6]

Здесь zip() перечисляет массивы параллельно и возвращает последовательность пар ( 2-элементные кортежи) с одним элементом из каждого массива. flatMap() создает 2-элементный массив из каждой пары и конкатенирует результат.

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

func mergeFunction<T>(one: [T], _ two: [T]) -> [T] {
    let commonLength = min(one.count, two.count)
    return zip(one, two).flatMap { [$0, $1] } 
           + one.suffixFrom(commonLength)
           + two.suffixFrom(commonLength)
}

Обновление для Swift 3:

func mergeFunction<T>(_ one: [T], _ two: [T]) -> [T] {
    let commonLength = min(one.count, two.count)
    return zip(one, two).flatMap { [$0, $1] } 
           + one.suffix(from: commonLength)
           + two.suffix(from: commonLength)
}
20
ответ дан Martin R 21 August 2018 в 00:49
поделиться
  • 1
    flatMap не создает «кортеж». zip создает кортежи; по сути, он дает массив кортежей. flatMap flattens! Простой map даст [[1, 2], [3, 4], [5, 6]]; flatMap удаляет лишний уровень массива. – matt 22 January 2016 в 19:31
  • 2
    @matt: Вы совершенно правы, я написал эту часть немного поспешно ... – Martin R 22 January 2016 в 20:17
  • 3
    Вы все еще не делаете правосудие. flatMap "конкатенирует результат" и в то же время удаляет тот массив, который он создал, оставляя только два элемента. Это изобретательность вашего решения. Конечно, я сразу же подумал о zip и надеялся, что вы его примете, но то, что вы здесь делаете, блестящее, делает небольшой массив, чтобы снова уничтожить его. Вы проходите через маленький массив как способ удаления кортежа кортежа, оставляя только два элемента. – matt 22 January 2016 в 20:34
  • 4
    :( Pfft, внезапно Swift требует, чтобы аргументы вызывались без разрушения кортежа. Например: let merged = zip (один, два) .flatMap {[$ 0.0, $ 0.1]} – Charlesism 15 July 2017 в 12:27
  • 5
    @Charlesism: Да, но это может измениться снова. Был обсужден в списке рассылки Swift evolution (например, здесь lists.swift.org/pipermail/swift-evolution-announce/2017-June/… ), я не знаю, что текущий статус является. – Martin R 15 July 2017 в 18:35

Если вы просто хотите чередовать два массива, вы можете просто сделать что-то вроде:

let maxIndex = max(one.count, two.count)
var mergedArray = Array<T>()
for index in 0..<maxIndex {
    if index < one.count { mergedArray.append(one[index]) }
    if index < two.count { mergedArray.append(two[index]) }
}

return mergedArray
5
ответ дан Charles A. 21 August 2018 в 00:49
поделиться
  • 1
    Я обновляю вопрос, чтобы быть более конкретным, я использовал ints как простой пример, это больше о слиянии двух массивов на основе индекса элемента массива (один за другим, где это возможно) – Neil Horton 22 January 2016 в 17:50
  • 2
    Вы все равно можете использовать описанный выше подход, просто напишите пользовательскую функцию сортировки вместо использования & lt; – Charles A. 22 January 2016 в 17:51
  • 3
    Im ищет вставку на основе позиции в массиве не по значению элемента i.e [one [0], two [0], one [1], two [1] и т. Д.] – Neil Horton 22 January 2016 в 17:53
  • 4
    Итак, вы просто хотите чередовать два массива? Я уточню свой ответ. – Charles A. 22 January 2016 в 17:54
  • 5
    Ну, flatmap не будет чередовать предметы. Вы могли бы использовать карту через кортеж ваших двух массивов, но я не думаю, что это было бы более ясно. – Charles A. 22 January 2016 в 18:00
Другие вопросы по тегам:

Похожие вопросы: