Извлекать данные из массива с элементами второго массива - PullRequest
0 голосов
/ 15 марта 2020

У меня есть один массив «users» со всеми пользовательскими данными и второй массив «userIds», имеющий идентификатор пользователя. Я должен выбрать пользователя из массива "users", используя массив "userIds"

struct User {
    let name: String
    let id: Int
}

let users: [User] = [User(name: "a", id: 1), 
                     User(name: "b", id: 2), 
                     User(name: "c", id: 3), 
                     User(name: "d", id: 4), 
                     User(name: "d", id: 5)]

let userIds = [2,3,2,5]

массив результатов, который мне нужен:

[User(name: "b", id: 2),
 User(name: "c", id: 3),
 User(name: "b", id: 2),
 User(name: "d", id: 5)]

, чтобы он мог иметь дублирующиеся данные в соответствии с данными в "userIds".

Теперь я попытался использовать функцию высшего порядка filter:

let result = users.filter { (user) -> Bool in
    return userIds.contains(user.id)
}

, но это удаляет дубликаты данных и вывод:

[User(name: "b", id: 2),
 User(name: "c", id: 3),
 User(name: "d", id: 5)]

Один из подходов, который я попробовал, использует l oop:

var result = [User]()

for i in userIds {
    result.append(users.filter({ $0.id == i }).first!)
}

, который дает желаемый результат, но если есть лучший подход, пожалуйста, предложите.

Ответы [ 2 ]

1 голос
/ 15 марта 2020

Вы можете решить эту проблему, используя first(where:) для поиска по users:

let result = userIds.compactMap { desiredDataValue in
    users.first(where: { $0.id == desiredDataValue })
}

Но если вы делаете это много, это, вероятно, ускорит процесс, если вы построите структуру данных, которая позволяет для быстрого поиска по значению "id". Вы должны сравнить производительность для себя и посмотреть, достаточно ли вы делаете это достаточно часто, чтобы это стоило:

let dictsByData = Dictionary(uniqueKeysWithValues:
    users
        .lazy
        .map { dict in
            (key: dict.id, value: dict)
        }
)

let result = userIds.compactMap { desiredDataValue in dictsByData[desiredDataValue]! }
result.forEach { print($0) }
0 голосов
/ 15 марта 2020

Через несколько копий и с помощью этого блога:

Я попытался сделать так:

let results = userIds.compactMap { (int) -> User? in
    var matchedUser: User?
    if users.contains(where: { (user) -> Bool in
        if user.id == int {
            matchedUser = user
        }
        return user.id == int
    }) {
        return matchedUser
    }
    return nil
}

и на игровой площадке я проверил счет, код был выполнен:

enter image description here

и кажется, что число меньше по сравнению с "для" l oop.

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