#swift
#swift
Вопрос:
Я фильтрую массив на основе содержащегося идентификатора. У меня есть четыре элемента в массиве с разными id
, но одинаковыми serviceId
, я фильтрую базовый массив, проверяя, совпадает ли идентификатор с идентификатором из другого массива.
let flattenArray = [
{
"id":1,
"name":"abc"
},
{
"id":2,
"name":"joe"
},
{
"id":3,
"name":"aby"
}
]
struct MainElement: Codable {
var id: Int?
var name: String?
}
typealias Main = [MainElement]
let toFilter = [
{
"id":"1a",
"serviceId":1
},
{
"id":"1b",
"serviceId":1
},
{
"id":"1c",
"serviceId":1
},
{
"id":"1d",
"serviceId":1
}
]
// MARK: - ServiceElement
struct ServiceElement: Codable {
var id: String?
var serviceId: Int?
}
typealias Service = [ServiceElement]
let filteredBill = Array(flattenArray).filter { service in
toFilter.contains(where: { $0.serviceId == service.id })}
Я хочу, чтобы отфильтрованный счет становился [{"id": 1, "name": "abc"}, {"id": 1, "name": "abc"}, {"id": 1, "name": "abc"}, {"id": 1, "name": "abc"}]
с тех пор, как serviceId появляется 4 раза
в настоящее время возвращается только один
Комментарии:
1. Не могли бы вы опубликовать правильный swift-код, словари записываются с помощью [], а не {} . А также объясняет связь между flattenArray и toFilter
2. @JoakimDanielson это массив объектов.
3. Как? Я переформатировал json с jsonformatter.curiousconcept.com /#
4. У вас есть массив «Service» и массив «Item», но вы хотите, чтобы в конце был массив Service, нет? Или это только JSON, который не анализируется?
5. Если я беру ваш код и вставляю его на игровую площадку, я получаю ошибки компиляции, поскольку он не swift, если это json, тогда опубликуйте его как таковой, но я не вижу смысла, потому что вопрос не в декодировании json, верно ?. Пожалуйста, опубликуйте воспроизводимый пример
Ответ №1:
Поскольку ваш код не является «допустимым» как таковой, мы можем предположить, что у вас есть a Service
и an Item
struct .
struct Service {
let id: Int
let name: String
}
struct Item {
let id: String
let serviceId: Int
}
Затем мы заполняем:
let services = [Service(id: 1, name: "abc"),
Service(id: 2, name: "joe"),
Service(id: 3, name: "aby")]
let items = [Item(id: "1a", serviceId: 1),
Item(id: "1b", serviceId: 1),
Item(id: "1v", serviceId: 1),
Item(id: "1d", serviceId: 1)]
И чтобы получить ваш результат, как я полагаю, вам нужен массив Service
из массива Item
.
Итак, вам нужно преобразование, а не фильтрация. Так что это map()
/ compactMap()
, а не filter()
:
let transformed = items.compactMap { anItem in
return services.first(where: { $0.id == anItem.serviceId })
}
Пояснения:
Для каждого Item
in items
мы проверяем, есть ли соответствующий Service
in services
. Если он есть в нем, мы возвращаем Service
найденное, иначе мы возвращаем nil
(и мы не добавляем его в преобразование).
С более ручным циклом for:
var transformed = [Service]()
for (_, anItem) in items.enumerated() {
if let serviceFound = services.first(where: { $0.id == anItem.serviceId }) {
transformed.append(serviceFound)
}
}