возвращает массив на основе количества содержимого swift

#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)
    }
}