Фильтрация объектов по конкретному объекту в этом значении

Итак, у меня есть список предметов, например, кроссовки. Я получаю эти объекты, анализируя данные JSON. Ниже приведен класс модели, который я использую для выполнения этой задачи.

@objcMembers class SneakerInfoTemp: Object, Decodable {
//    dynamic var id = UUID().uuidString

    //list of dynamic properties that will be deserialized from the json and then passed into realm
    dynamic var brand: String?
    dynamic var category: String?
    dynamic var colorway: String?
    dynamic var currentdescription: String?
    dynamic var designer: String?
    dynamic var imagesrc: String?
    dynamic var maincolor: String?
    dynamic var name: String?
    dynamic var nickname: String?
    dynamic var price: String?
    dynamic var productlink: String?
    dynamic var productlinkhref: String?
    dynamic var releasedate: String?
    dynamic var silhouette: String?
    dynamic var technology: String?
    dynamic var webscraperorder: String?
    dynamic var webscraperstarturl: String?

    enum CodingKeys: String, CodingKey {
        case brand, category, colorway, designer, imagesrc, maincolor, name, nickname, price, productlink, productlinkhref, releasedate, silhouette, technology,webscraperorder,webscraperstarturl,currentdescription
    }

    required init(from decoder: Decoder) throws
    {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        //sneaker information that will be decoded
        //made optional due to the fact that some fields don't exist with every shoe
        brand = try? container.decode(String.self, forKey: .brand)
        category = try? container.decode(String.self, forKey: .category)
        colorway = try? container.decode(String.self, forKey: .colorway)
        currentdescription = try? container.decode(String.self, forKey: .currentdescription)
        designer = try? container.decode(String.self, forKey: .designer)
        imagesrc = try? container.decode(String.self, forKey: .imagesrc)
        maincolor = try? container.decode(String.self, forKey: .maincolor)
        name = try? container.decode(String.self, forKey: .name)
        nickname = try? container.decode(String.self, forKey: .nickname)

        price = try? container.decode(String.self, forKey: .price)
        productlink = try? container.decode(String.self, forKey: .productlink)
        productlinkhref = try? container.decode(String.self, forKey: .productlinkhref)
        releasedate = try? container.decode(String.self, forKey: .releasedate)
        silhouette = try? container.decode(String.self, forKey: .silhouette)
        technology = try? container.decode(String.self, forKey: .technology)
        webscraperorder = try? container.decode(String.self, forKey: .webscraperorder)
        webscraperstarturl = try? container.decode(String.self, forKey: .webscraperstarturl)
        super.init()
    }


    required init()
    {
        super.init()
    }

    override class func primaryKey() -> String? {
        return "name"
    }

    required init(value: Any, schema: RLMSchema)
    {
        super.init(value: value, schema: schema)
    }

    required init(realm: RLMRealm, schema: RLMObjectSchema)
    {
        super.init(realm: realm, schema: schema)
    }


}

Когда все сказано и сделано, я получаю список объектов. Проблема в том, что некоторые объекты являются дубликатами. Я пытался использовать набор для их удаления, но набор не может определить разницу между объектами. Я как бы хочу взять этот список объектов и добавить их в набор на основе некоторого свойства, скажем, имени

Я хочу сделать что-то вроде этого

   let objectSet = Set((sneakersTemp.sneakers?.brands?.adidas.map { $0.name })!)
        print(objectSet.count)

Он возвращает все уникальные имена, но в любом случае я могу получить все уникальные объекты.

Пользователь .filter вместо .map

Agisight 08.04.2019 16:49

Затем базовое равенство на имени

ielyamani 08.04.2019 16:50

да, но вернет ли он мне объекты? или просто имена снова

Bo Jackson 08.04.2019 16:50

@ielyamani не могли бы вы показать мне пример, пожалуйста

Bo Jackson 08.04.2019 16:51
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Используйте .filter вместо .map. Попробуй это

let array : [Obj] = sneakersTemp.sneakers?.brands?.adidas
let filtered = filterUnique(array: array)

где Obj — ваш класс/структура для массива sneakersTemp.sneakers?.brands?.adidas (или его суперкласс с имя переменной: строка)

func filterUnique(array : [Obj]) -> [Obj] {
    var filtered : [String] = []
    let objectSet = array.filter({ obj -> Bool in
        if filtered.contains(obj.name) {
            return false
        }
        filtered.append(obj.name)
        return true
    })
    print(objectSet.count)
}

собираюсь попробовать это сейчас. если это работает плохо, примите ответ

Bo Jackson 08.04.2019 16:57

Как дела?

Agisight 08.04.2019 17:35

случай, который вы указали, специфичен для моего примера или сейчас

Bo Jackson 08.04.2019 18:29

потому что objsetSet по-прежнему содержит все значения, когда я использую ваш код

Bo Jackson 08.04.2019 18:36

каковы ваши условия для фильтрации?

Agisight 08.04.2019 18:47

Я хочу, чтобы он не добавлялся в набор, если там есть объект с таким же именем, как у него

Bo Jackson 08.04.2019 18:49

есть идеи случайно?

Bo Jackson 08.04.2019 19:12

я изменил ответ на ваш случай

Agisight 10.04.2019 09:26
Ответ принят как подходящий

Чтобы удалить дубликаты с помощью Set, тип должен соответствовать Hashable.

Для упрощения предположим, что класс SneakerInfoTemp определен так:

class SneakerInfoTemp {
    let name: String
    let price: Double

    init(name: String, price: Double) {
        self.name = name
        self.price = price
    }
}

Соответствуем необходимым протоколам:

extension SneakerInfoTemp: Equatable {
    static func == (lhs: SneakerInfoTemp, rhs: SneakerInfoTemp) -> Bool {
        return lhs.name == rhs.name
    }
}

extension SneakerInfoTemp: Hashable {
    func hash(into hasher: inout Hasher) {
        hasher.combine(name)
    }
}

Итак, учитывая массив кроссовок:

var array = [SneakerInfoTemp(name: "a", price: 1),
             SneakerInfoTemp(name: "b", price: 2),
             SneakerInfoTemp(name: "a", price: 3),
]

Вы можете создать набор уникальных элементов, используя Set:

let set = Set(array)

попробую и это

Bo Jackson 08.04.2019 17:19

Другие вопросы по теме