Есть ли более функциональный способ переставить массив в словарь - PullRequest
2 голосов
/ 07 февраля 2020

Мне интересно, есть ли лучший и функциональный способ перегруппировать массив в словарь, где каждый ключ - это другой массив с 2 элементами?

Я сделал эти два примера, но я все еще изучаю функциональное программирование и не смог найти лучшего решения. Спасибо всем!

[EDIT]

@ bcal дал отличное решение этой проблемы; и я думаю, что любой желающий может внести свой вклад в другие решения!

let myObjArray = ["A", "B", "C", "F", "G", "H", "I", "J", "K"]
var myIndexTwoObjArr: [Int: [String]] = [:]

// first way
var index = 0
for item in myObjArray {
    if myIndexTwoObjArr[index] == nil {
        myIndexTwoObjArr[index] = [item]
    }else if myIndexTwoObjArr[index]!.count < 2  {
        myIndexTwoObjArr[index]?.append(item)
        index += 1
    }
}

print("first way")
myIndexTwoObjArr.forEach{print($0)}

// second way
index = 0
myObjArray.forEach { item in
    if myIndexTwoObjArr[index] == nil {
        myIndexTwoObjArr[index] = [item]
    }else if myIndexTwoObjArr[index]!.count < 2  {
        myIndexTwoObjArr[index]?.append(item)
        index += 1
    }
}

print("second way")
myIndexTwoObjArr.forEach{print($0)}

// third way [thanks to bcal answer]
myIndexTwoObjArr = [:]
myIndexTwoObjArr = [Int: [String]](myObjArray.enumerated().map({($0.0/2, [$0.1])}), uniquingKeysWith: +)

print("third way [thanks to bcal answer]")
myIndexTwoObjArr.forEach{print($0)}

Печать результатов:

result print

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Dictionary имеет инициализатор, который принимает Sequence пар ключ / значение, и закрытие для разрешения пар с дублирующимися ключами. https://developer.apple.com/documentation/swift/dictionary/3127161-init

myIndexTwoObjArr = [Int: [String]](
    myObjArray.enumerated().map({($0.0/2, [$0.1])}),
    uniquingKeysWith: +
)

Первый аргумент - это функциональная последовательность ...

enumerated преобразует элементы вашего массива в последовательность (Int, String) кортежи, где первое значение в кортеже является индексом элемента.

map преобразует кортежи (Int, String) в (Int, [String]) кортежи, где первое значение является индексом ÷ 2, а Второе значение - Array, содержащее один String.

Второй аргумент инициализатора Dictionary - это замыкание для объединения массивов с соответствующими ключами.

0 голосов
/ 07 февраля 2020

Вы можете попробовать это.

var index: Int = 0
let myIndexTwoObjArr = Dictionary(grouping: myObjArray, by: { _ -> Int in
    index += 1
    return index
})

Надеюсь, это поможет. :)

...