Создать многомерный массив на основе значения ключа - PullRequest
0 голосов
/ 30 января 2019

У меня есть array из MyData объектов (MyData - это struct):

[
MyData(id: 3, locale: "en", title: "p1", date: "10/15/2019"), 
MyData(id: 3, locale: "de", title: "p2", date: "11/12/2019"), 
MyData(id: 32, locale: "fr", title: "free", date: "10/11/2019"), 
MyData(id: 15, locale: "de", title: "free", date: "10/11/2019"), 
MyData(id: 19, locale: "de", title: "p1", date: "11/10/2019"),
MyData(id: 19, locale: "de", title: "p2", date: "11/10/2019"),
MyData(id: 19, locale: "de", title: "p3", date: "11/10/2019"),
]

Я бы хотел сгруппировать этот массив (или даже намеренно создать новый)) на основе ключа id.

Результат должен быть таким:

[
[MyData(id: 3, locale: "en", title: "p1", date: "10/15/2019"), MyData(id: 3, locale: "de", title: "p2", date: "11/12/2019")], 
MyData(id: 32, locale: "fr", title: "free", date: "10/11/2019"), 
MyData(id: 15, locale: "de", title: "free", date: "10/11/2019"), 
[MyData(id: 19, locale: "de", title: "p1", date: "11/10/2019"),MyData(id: 19, locale: "de", title: "p2", date: "11/10/2019"),MyData(id: 19, locale: "de", title: "p3", date: "11/10/2019")]
]

, то есть: массивы с одинаковым идентификатором должны образовывать новый массив.

Конечно, я мог бы просто зациклить первый массив и создать второй, но я хотел знать, может ли Swift что-то сделать со своими фильтрами.Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Есть еще два способа.Так же, как примечание здесь.

    struct MyData{
        let id : Int
        let locale : String
        let title : String
        let date : String
    }

    let data = [
        MyData(id: 3, locale: "en", title: "p1", date: "10/15/2019"),
        MyData(id: 3, locale: "de", title: "p2", date: "11/12/2019"),
        MyData(id: 32, locale: "fr", title: "free", date: "10/11/2019"),
        MyData(id: 15, locale: "de", title: "free", date: "10/11/2019"),
        MyData(id: 19, locale: "de", title: "p1", date: "11/10/2019"),
        MyData(id: 19, locale: "de", title: "p2", date: "11/10/2019"),
        MyData(id: 19, locale: "de", title: "p3", date: "11/10/2019"),
    ]


    data.reduce(into: [:]) { ( result, next) in
    if result.keys.contains(next.id){
        (result[next.id] as? [MyData]).map{result[next.id] =  $0 + [next] }
        ([result[next.id]] as? [MyData]).map{result[next.id] = $0 + [next]}
    }
    else{ result[next.id] = next }
}.values


    Set(data.map{$0.id}).map{id -> Any in
        let result = data.filter{$0.id == id}
        return result.count == 1 ? result.first! : result
    }
0 голосов
/ 30 января 2019

Вы можете использовать функции высшего порядка в этом точно, но не 100 %, чтобы полностью получить желаемый результат, но большую его часть, так как желаемый тип массива - :[Any].

Проверьте код ниже:

var myGroup = Dictionary(grouping: arrayOne, by: { $0.id }) // group each element by id -type of: [Int:[Data]]
let resultArray = myGroup.map { $0.value } //map out the elements without the id key. -type of: [[Data]]

//Create hetro Array so we can use it later to append the results
var myHetroArray: [Any] = []
// loop each array in the result array and check if it only contains 1 element if so append that one element to the hetro array otherwise just append the whole thing.
for array in resultArray {
    if array.count ==  1 {
    myHetroArray.append(array.first!)
    } else {
        myHetroArray.append(array)
    }
}

print(myHetroArray) // produce the desired result.

Выход: [
[Данные (id: 19, локаль: "de", заголовок: "p1", дата: "10.11.2009"), данные (id: 19, локаль: "de", заголовок: "p2", дата: "11.11.2009"), Данные (id: 19, языковой стандарт: «de», заголовок: «p3», дата: «10.11.2009»)],
Данные (id: 15, языковой стандарт: «de», заголовок: «свободный»", дата:" 10/11/2019 "),
Данные (id: 32, языковой стандарт:" fr ", заголовок:" free ", дата:" 10/11/2019 "),
[Данные(id: 3, языковой стандарт: «en», заголовок: «p1», дата: «15.10.2009»), Data (id: 3, языковой стандарт: «de», заголовок: «p2», дата: «11/ 12/2019 ")]
]

...