Итак, на первый взгляд это казалось довольно простой задачей, которую я решил решить, но я нашел несколько уловок, и мое текущее конечное решение действительно ужасно, поэтому мне любопытно посмотреть, что вы, ребята, можете придуматьс
у меня есть класс, OptionalObject
.У него четыре свойства:
let prop1: String?
let prop2: String?
let prop3: String?
let prop4: String?
У меня есть массив из тысячи этих OptionalObject
объектов, и я гарантирую, что нет двух объектов с одинаковыми свойствами.
EX: (OptionalObject: prop1, prop2, prop3, prop4
Obj1: ABC, 123, Hello, Goodbye
Obj2: DEF, 456, nil, nil
Obj3: nil, nil, Hello, Goodbye
Obj4: nil, nil, Hello, nil
Obj5: ABC, nil, nil, nil
Obj6: ABC, nil, Hello, Goodbye
Obj7: DEF, 123, nil, Goodbye
Obj8: DEF, nil, nil, nil
...
, а затем у меня есть отдельный объект другого класса, который имеет все 4 строки (необязательно)
(ConcreteObject: arg1: String, arg2: String, arg3: String, arg4: String)
Я хочу найти лучшее совпадение OptionalObject
с моим ConcreteObject
, основанное на этих четырех свойствах.
Что я могу придумать для двух способов сделать это, один из них состоит в том, чтобыиспользуйте filter
на всех OptionalObjects
, другой - вручную перечислять все OptionalObjects
, иметь вложенные операторы if
для проверки свойств (что фактически равно filter
в любом случае)
ЕслиЯ должен был отфильтровать, это может быть что-то вроде этого:
let matchingOptionalObject = optionalObjectsArray.filter {return $0.prop1 == arg1 && $0.prop2 == arg2 && $0.prop3 == arg3 && $0.prop4 == arg4}
и бум У меня теперь есть один объект, который соответствует ... но только если это точное соответствие.
Если мой ConcreteObject
имеет (DEF, 123, Hello, Goodbye)
Я бы не получил ни одного совпадения, потому что нет OptionalObjects
совпадения точно.
Я бы ожидалвозврат Obj3, Obj4, Obj7, Obj8
Итак, естественно, я думаю, хорошо, давайте сначала посмотрим, какие аргументы у нас не как nil, а затем сконструируем запрос соответственно.
Для этогоНапример, я собираюсь притвориться, что есть только два свойства, поэтому их легче понять:
let matchingOptionalObject = optionalObjectsArray.filter {
if $0.prop1 != nil {
if $0.prop2 != nil {
return $0.prop1 == arg1 && $0.prop2 == arg2
} else {
return $0.prop1 == arg1
}
} else {
if $0.prop2 != nil {
return $0.prop2 == arg2
} else {
return false
}
}
}
Но тогда проблема в том, что, поскольку существует 4 свойства, существует как минимум 10 различных возможностей уникальности nil
аргументов, которые нам нужно охватить, и это становится действительно очень уродливым
Что у меня сейчас есть, у меня есть куча уродливых if
утверждений, проверяющих комбинацию nil
аргументов, и затемпостроение запроса filter
соответственно ...
Что ж, нам нужно двигаться дальше, так что, я думаю, мы можем разобраться с ним и открыть проблему, чтобы найти лучшее решение позже, но потоместь еще одно требование, которое делает это решение неработоспособным ...
. Это означает, что каждое свойство имеет различный вес.
Два правила выбора лучшего маtch при наличии нескольких совпадений:
1) Выберите совпадение, у которого наибольшее количество совпадающих свойств
2) Если совпадения имеют одинаковое количество совпадающих свойств, выберите совпадение с наибольшим весом.
Prop1 имеет наибольший вес
Prop2 имеет наименьший
Итак, с примером ConcreteObject
: (DEF, 123, Hello, Goodbye)
Соответствует OptionalObjects
:
Obj3: nil, nil, Hello, Goodbye
Obj4: nil, nil, Hello, nil
Obj7: DEF, 123, nil, Goodbye
Obj8: DEF, nil, nil, nil
Мы бы выбрали Obj7
в качестве наилучшего совпадения, потому что у него есть 3 свойства сопоставления
Но, скажем, для другого примера с новым ConcreteObject
и новым набором OptionalObjects
, у нас есть это совпадение:
Наш новый Matched OptionalObjects
:
New1: nil, 999, nil, NiHao
New2: XYZ, 999, nil, nil
Мы бы выбрали New2
, потому что, хотя New1
и New2
оба имеют 2 совпадающих свойства, New2
имеет соответствующие свойства с более высоким весом.
Итак, возникает дилемма.
Я надеюсь, что просто не помню некоторые ключевые понятия много лет назад в моих алгоритмах старшекурсниковкласс, и что есть какое-то чистое решение (может быть, даже то, что Swiftобеспечивает), но я почти сошел с ума - так что любые предложения или идеи, которые есть у кого-либо, более чем приветствуются