Nano Hash - криптовалюты, майнинг, программирование

Как настроить NSPredicate для суммирования значений свойств внутри словарей в массиве словарей в iOS?

Вопрос. Как настроить NSPredicate для суммирования значений свойств внутри словарей в массиве словарей в iOS?

Примечание: ответ должен быть одной строкой, используемой в аргументе формата объекта NSPredicate. Например: var pred1:NSPredicate = NSPredicate.init(format: *ANSWER*)


Предположим, у меня есть следующий словарь:

var ticketState:Dictionary =
[
    "orderTotal":1.2,
    "payments":
    [
        [
            "authCode":"12345",
            "isVoid":"false",
            "amount":1.0
        ],
        [
            "authCode":"54321",
            "isVoid":"false",
            "amount":0.2
        ]
    ],
    "associatedWithReturn":false
]

Теперь я хочу, чтобы NSPredicate проверял, равна ли сумма всех сумм сумме заказа.

Что-то типа:

var cond1:String = "sum($payments[].amount == $orderTotal)"

Примечание. Я не могу использовать фильтрацию массива или второй предикат.

Я могу получить доступ к первой сумме платежа следующим образом:

var cond1:String = "$payments[1].amount > 0" //works, returns true

Это вернет true. Я просто хочу проверить, что сумма всех сумм в платежах равна общей сумме заказа. Это должна быть простая операция, определяемая одним предикатом.

Как мне написать однострочное объявление NSPredicate, которое выполняет это?


Примечание: есть очень конкретная причина, по которой мне нужна однострочная, одиночная строка формата инициализации NSPredicate. Но это деталь реализации; не беспокойтесь об этом, потому что у кого-то другого может быть другая причина, чем у меня, для необходимости такого же типа инициализации.

21.01.2016

  • Я думаю, вам следует поискать, прежде чем спрашивать stackoverflow.com/a/11932302/1403732 21.01.2016
  • Я искал, на самом деле я просмотрел около 10 разных вопросов и ответов, прежде чем задавать. Ссылка, которую вы только что дали, не дает прямого ответа на мой вопрос — хотя она дает хороший намек, на самом деле она не показывает работающий NSPredicate, который делает то, что я просил. Я смог понять это из того, что они сказали, но вам не нужно было минусовать мой вопрос. Впрочем, спасибо за подсказку. 21.01.2016
  • Извините, сначала мне не нравится ваш вопрос, но помог вам, а во-вторых, я не хочу ваших голосов из-за первого)) 21.01.2016
  • И человек, если вы опубликуете правильный ответ, я проголосую за него! 21.01.2016
  • Я разместил правильный ответ и код, поэтому для NSPredicate это должна быть одна строка. Потому что GKRule принимает NSPredicate в качестве аргумента. (Использование GKRuleSystem для создания бизнес-правил.. ›D) 21.01.2016

Ответы:


1

Это собственное решение Swift, которое использует встроенные функции.

  • map, чтобы поместить значения amount в массив
  • reduce чтобы добавить значения

let payments = ticketState["payments"] as! [[String:AnyObject]]
let amountSum = payments.map{$0["amount"] as! Double}.reduce(0, combine: {$0 + $1})
21.01.2016
  • Просто к вашему сведению, ответ должен быть NSPredicate, чтобы проверить, равна ли сумма всех сумм общей сумме заказа. (Все дело в том, что я привожу аргумент в пользу GKRule, классного нового механизма правил Apple, который дебютировал в iOS 9.) Но приятно посмотреть, как это будет выглядеть не как NSPredicate, для справки: D 21.01.2016
  • Вы не упомянули GKRule в своем вопросе… ;-) 21.01.2016
  • Что ж, я пытался не задавать вопрос #import ненужными зависимостями :D В большинстве вопросов о поиске NSPredicate во вложенных коллекциях и наборах GKRule не упоминается. Я подумал, что было бы лучше просто оставить это в том, что говорится в заголовке вопроса. Извините, если заголовок не был более ясным, я знаю, что важен контекст. Я обновлю исходный вопрос, чтобы повторить сам заголовок, как он должен был быть сформулирован, и +1 вам за ответ, который, как я подозреваю, поможет другим. 21.01.2016

  • 2

    Используйте следующий код, чтобы получить сумму

    var totalAmount:Float = (ticketState.valueForKeyPath("[email protected]") as! NSNumber).floatValue;
    

    Теперь вы можете сравнить его или сделать все, что хотите.

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

    https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueCoding/Articles/CollectionOperators.html

    21.01.2016
  • Вы можете привести результат к Float напрямую: let totalAmount = ticketState.valueForKeyPath("[email protected]") as! Float, но тип коллекции должен быть NSDictionary. Нативные типы коллекций Swift не реагируют на valueForKeyPath 21.01.2016
  • Прошу прощения, в оригинальном заголовке вопроса не было ясно, что мне нужен оператор инициализации объекта NSPredicate. Я признаю, что строка, указанная в вашем ответе, технически может использоваться в качестве аргумента формата в таком утверждении, и я не сделал исходный вопрос достаточно явным, чтобы это было требованием для правильного ответа. +1 однако большую часть пути туда. 21.01.2016
  • На самом деле я рассматривал цель .. не так (предикат или KVC).. для любой задачи .. не всегда необходимо, чтобы нам нужно было через предикат или KVC .. решение - единственная необходимая вещь ... Я видел ваш ответ .. это тоже правильный путь .. я тоже узнал много нового из этого .. спасибо и за это тоже 21.01.2016

  • 3
    var cond1:String = "[email protected] == $orderTotal"
    
    var pred1:NSPredicate = NSPredicate.init(format: cond1)
    var rule1:GKRule = GKRule.init(predicate: pred1, assertingFact:"completeable", grade:1.0)
    var ruleSys:GKRuleSystem = GKRuleSystem.init()
    
    ruleSys.addRule(rule1)
    ruleSys.state.addEntriesFromDictionary(ticketState)
    ruleSys.evaluate()
    print(ruleSys.facts)
    

    Возвращает ["completeable"].

    Спасибо sage444 за подсказку, которая привела меня к этому.

    Другими словами:

    Быстрый:

    var pred1:NSPredicate = 
        NSPredicate.init(format:  "[email protected] == $orderTotal")
    

    Цель С:

    NSPredicate *pred1 = 
        [[NSPredicate alloc]initWithFormat:@"[email protected] == $orderTotal"];
    

    Моя цель — инициализировать объект Apple GameplayKit GKRule, который принимает объект NSPredicate в качестве аргумента. Однако я думаю, что у него может быть много других применений.

    21.01.2016
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..