Быстрый функциональный способ получить один элемент из подмассива - PullRequest
0 голосов
/ 02 октября 2018

У меня есть следующая функция (пример), которую я хотел бы написать функциональным способом:

func passengerForId(_ id: Int) -> Passenger?
{
    for car in cars
    {
        for passenger in car.passengers
        {
            if passenger.id == id
            {
                return passenger
            }
        }
    }
    return nil
}

Что было бы лучшим способом?

Я пробовалследующее:

func passengerForId(_ id: Int) -> Passenger?
{
    return cars.first(where: { $0.passengers.contains(where: { $0.id == id } ) })
}

Однако это, очевидно, возвращает автомобиль, содержащий запрошенного пассажира, а не самого пассажира.

Другой вариант будет выглядеть примерно так:

func passengerForId(_ id: Int) -> Passenger?
{
    let passengers = cars.flatMap { car in car.passengers }
    return passengers.first(where: { $0.id == id })
}

или

func passengerForId(_ id: Int) -> Passenger?
{
    return cars.flatMap { car in car.passsengers.filter { $0.id == id }}.first
}

Однако, это кажется менее эффективным, чем оригинал, поскольку оно будет проходить по всем областям.

Есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 02 октября 2018

Вы можете создать (ленивую) сводную коллекцию всех пассажиров и выбрать первую подходящую:

func passengerForId(_ id: Int) -> Passenger? {
    return cars.lazy.flatMap({ $0.passengers }).first(where: { $0.id == id } )
}
...