Swift - объединение двух массивов кортежей на основе их значений - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть сценарий, в котором у меня есть два массива кортежей.

tuple1 = [(score1, index1), (score2, index2), (score3, index3)]
tuple2 = [(date1, index1), (date2, index2), (date3, index4)]

Я хочу получить оценки и даты из этих кортежей и создать новый массив кортежей, который будет содержать счет идата с таким же индексом, как этот:

tuple3 = [(score1, date1), (score2, date2)]

Как я могу это реализовать?Какова лучшая практика, чтобы следовать в этом сценарии? Примечание: Массивы могут быть разных размеров

Моя реализация сценария выглядит следующим образом:

var tuple3 = [(Double, Date)]()
    for (i,psa) in tuple1.enumerated() {

        let date = tuple2.filter({ $0.1 == i })

        if date.count == 1 {
            let newTuple = (tuple1.0, date[0].0)
            tuple3.append(newTuple)
        }
    }

Это правильный путьсделать это или есть лучший?

Ответы [ 4 ]

0 голосов
/ 25 сентября 2018
let tuple1 = [("score1", "index1"), ("score2", "index2"), ("score3", "index3")]
let tuple2 = [("date1", "index1"), ("date2", "index2"), ("date3", "index4")]

let t2Dict = tuple2.reduce(into: [String:String]()) { (dict, args) in
    let (date, index) = args
    dict[index] = date
}

let tuple3 = tuple1.compactMap { args -> (String, String)? in
    let (score, index) = args
    guard let date = t2Dict[index] else { return nil }
    return (score, date)
}

Это не так красиво, как другие, но гораздо эффективнее сначала свернуть один из кортежей в словарь.

0 голосов
/ 25 сентября 2018

Это должно сработать:

let tuple3 = tuple1.compactMap({  (scoreInTuple1, indexInTuple1) -> (String, String)? in
    if let tupleIn2 = tuple2.first(where: { (scoreInTuple2, index2InTuple2) in index2InTuple2 == indexInTuple1 }){
        return (scoreInTuple1, tupleIn2.0)
    }
    return nil
})

(String, String) следует изменить на реальный тип / класс score & date1.Кроме того, index2InTuple2 == indexInTuple1 может быть изменено также, если это пользовательский тип / класс, который не может быть Equatable.

С примером кода до:

let tuple1 = [("score1", "index1"), ("score2", "index2"), ("score3", "index3")]
let tuple2 = [("date1", "index1"), ("date2", "index2"), ("date3", "index4")]

Журнал отладки после:

print("tuple3: \(tuple3)")

Вывод:

$> tuple3: [("score1", "date1"), ("score2", "date2")]
0 голосов
/ 25 сентября 2018

Это может быть то, что вы ищете:

let tuple1 = [("score1", "index1"), ("score2", "index2"), ("score3", "index3")]
let tuple2 = [("date1", "index1"), ("date2", "index2"), ("date3", "index4")]

let filtered = tuple1.filter {tuple2.map{$0.1}.contains($0.1)}
let result = filtered.map {tuple in
    return (tuple.0, tuple2.first(where: {$0.1 == tuple.1})!.0)
}

print (result)  // [("score1", "date1"), ("score2", "date2")]

Я использую Strings для простоты, просто убедитесь, что вы используете Equatable объекты в ваших кортежах.

0 голосов
/ 25 сентября 2018

Можно попробовать

let v1 = [("1","2"),("3","4")]

let v2 = [("1A","2A"),("3A","4A")]

let res = zip(v1,v2).map { ($0.0 , $1.0) } // [("1", "1A"), ("3", "3A")]

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