在字段中应用多个搜索

时间:2018-02-26 07:00:50

标签: java kotlin

fun getMatchingContactsFromSearch(startDate: String?, endDate: String?, whereMet: String?, eventName: String?, product: String?, service: String?): Observable<List<String>> {
{
    if ((eventName!!.isNotEmpty()) && whereMet!!.isEmpty() && (startDate!!.isEmpty() && endDate!!.isEmpty())&& product!!.isEmpty()&& service!!.isEmpty()) {

    } else if ((whereMet!!.isNotEmpty()) && eventName!!.isEmpty() && (startDate!!.isEmpty() && endDate!!.isEmpty())&& product!!.isEmpty()&& service!!.isEmpty()) {

    } else if ((startDate!!.isNotEmpty() && endDate!!.isNotEmpty()) && eventName!!.isNotEmpty() && whereMet!!.isEmpty()&& product!!.isEmpty()&& service!!.isEmpty()) {

    } else if ((startDate!!.isNotEmpty() && endDate!!.isNotEmpty()) && eventName!!.isEmpty() && whereMet!!.isNotEmpty()&& product!!.isEmpty()&& service!!.isEmpty()) {

    } else if ((eventName!!.isNotEmpty() && whereMet!!.isNotEmpty()) && ((startDate!!.isEmpty() && endDate!!.isEmpty()))&& product!!.isEmpty()&& service!!.isEmpty()) {

    } else if (eventName!!.isEmpty() && whereMet!!.isEmpty() && (startDate!!.isNotEmpty() && endDate!!.isNotEmpty())&& product!!.isEmpty()&& service!!.isEmpty()) {

    } else if (eventName!!.isNotEmpty() && whereMet!!.isNotEmpty() && startDate!!.isNotEmpty() && endDate!!.isNotEmpty()&& product!!.isEmpty()&& service!!.isEmpty()) {

    } else  {

    }
}

这是我的多项搜索代码我有2个以上的字段搜索产品和服务我也要申请条件但是它似乎非常复杂,应用搜索条件两个以上的字段可以任何人建议我如何将搜索条件应用于另外两个字段或给我一些其他方式,以便我们可以从listOfData中搜索它。

1 个答案:

答案 0 :(得分:1)

您需要实现的是一个简单的and条件(我假设您需要and语义进行搜索。

我将向您展示这种方法,您可以在您的应用中使用此类搜索。

想象一下你有一个类Data,如此:

data class Data(val a: String? = null, val b: String? = null, val c: String? = null)

让我们引入谓词类型,它只是函数的别名:

typealias Predicate<T> = T.() -> Boolean

因此,检查a类的属性Data的谓词可能如下所示:

val isASomething : Predicate<Data> = { a == "something" }
val data = Data(a = "something")
data.isASomething() // true

由于我们需要and语义,因此我们创建一个辅助函数,将任意数量的谓词与逻辑and组合在一起:

fun <T> and(vararg predicates: Predicate<T>): Predicate<T> {
  return predicates.fold({ true }) { previous: Predicate<T>, next: Predicate<T> ->
    {
      previous() && next()
    }
  }
}

总而言之,您可以编写一个方法,使用您的条件组件来搜索对象列表:

fun List<Data>.findByProps(aQuery: String? = null, bQuery: String? = null, cQuery: String? = null): List<Data> {

  val predicates = mutableListOf<Predicate<Data>>()
  if (aQuery != null) predicates += { a == aQuery }
  if (bQuery != null) predicates += { b == bQuery }
  if (cQuery != null) predicates += { c == cQuery }
  if (predicates.isEmpty()) throw IllegalArgumentException("At least one query must have a value")
  val criteria = and(*predicates.toTypedArray())
  return this.filter { it.criteria() }
}

让我们测试一下:

val data = listOf(
    Data("a", "b", "c"),
    Data("a", "1", "2"),
    Data("a", "1", "c")
)
println(data.findByProps(aQuery = "a")) // [Data(a=a, b=b, c=c), Data(a=a, b=1, c=2), Data(a=a, b=1, c=c)]
println(data.findByProps(bQuery = "1")) // [Data(a=a, b=1, c=2), Data(a=a, b=1, c=c)]
println(data.findByProps(aQuery = "a", cQuery = "c")) // [Data(a=a, b=1, c=2), Data(a=a, b=1, c=c)]

您现在可以轻松地根据您的情况调整此方法:

class Contact {
  ...
}

fun List<Contact>.search(startDateQuery: String? = null, endDateQuery: String? = null, whereMetQuery: String? = null, eventNameQuery: String? = null, productQuery: String? = null, serviceQuery: String? = null) {
      val predicates = mutableListOf<Predicate<Contact>>()
      if (startDateQuery != null) predicates += { startDate == startDateQuery }
      if (endDateQuery != null) predicates += { endDate == endDateQuery }
      if (whereMetQuery != null) predicates += { whereMet == whereMetQuery }
      if (eventNameQuery != null) predicates += { eventName == eventNameQuery }
      if (productQuery != null) predicates += { product == productQuery }
      if (serviceQuery != null) predicates += { service == serviceQuery }
      if (predicates.isEmpty()) throw IllegalArgumentException("At least one query must have a value")
      val criteria = and(*predicates.toTypedArray())
      return this.filter { it.criteria() }
}

并使用它:

val contacts : List<Contact> = getContacts()
val metAtHall = contacts.search(whereMetQuery = "Hall")