質問

OKこれまでのところ大成功なしに頭を傷つけているものです。非常に長い質問のために事前に事前に申し訳ありません...

これを使用しています lucene query parser これを生成する文字列/クエリを解析するデータ構造の種類:

// Notice that the repetition of 'field3' is on purpose
Sample String: field1:val1 AND field2:val2 OR field3:val3 AND field3:val4
Result:
    { left: { field: "field1", term: "val1" },
      operator: "AND"
      right: {
          left: { field: "field2", term: "val2" },
          operator: "OR"
          right: { 
              left: {field: "field3", term: "val3" },
              operator: "AND",
              right: {
                   field: "field3",
                   term: "val4"
              }
          }
      }
.


次のことを得るためにそのオブジェクトに繰り返す必要があります。

[ [{ field: "field1", term: "val1"},
   { field: "field2", term: "val2"}
  ],
  [{ field: "field3", term: "val3"},
   { field: "field3", term: "val4"}
  ]
]
.

これを説明しようとすると、アイデアは各子配列が "OR"で区切られている配列の配列を作成することですが、子配列内の各オブジェクトは "and"区切りフィールドを表します。私は上記のコードは私よりもそれをよく説明していますが

更新されたコード coffeeScript lo-dash 、ごめんなさい):

groups = []     
createGroups = (item, previousGroup, previousOperator) ->
    currentGroup = if _.isArray previousGroup then previousGroup else []

    # keyVal = {}
    # keyVal[item.left?.field or item.field] =  item.left?.term or item.term
    obj = fieldName: item.left?.field or item.field, val: item.left?.term or item.term

    if previousOperator?.toUpperCase() is 'AND'
        currentGroup.push obj
    else
        currentGroup = [obj]

    if _.isObject item.right
        createGroups(item.right, currentGroup, item.operator)

    groups.push currentGroup
.

このコードは、私が望むものをやるだけでなく、groupsアレイに関数の外で宣言されているが、関数の直接のように使われているが、それは非常に理想的ではありませんが、私は生きることができますそれを使って。

しかし、それはすべてのグループのようなすべてのグループを複製します。

[ [ {field: "field1", val:val1}, {field: "field2" val:val2} ], [ {field: "field1":val1}, {field: "field2", val:val2} ], ...]
.

今のところ私は、上記の関数が正しい結果を返す場合は、実行する必要があります。

を返す場合は、_.uniq(groups)を使用する必要があります。

あなたの助けをありがとう

役に立ちましたか?

解決

これはそれをするべきだと思います:

createGroups = (item, previousGroup) ->
  subroutine = (item, previousGroup) ->
    if typeof item is "object"
      unless item.operator
        if !item.left
          previousGroup.push item  
        else
          previousGroup.push item.left
        previousGroup
      if item.operator is "AND"
        currentGroup = subroutine(item.left, previousGroup)
        currentGroup = subroutine(item.right, currentGroup)
        currentGroup and groups.push(currentGroup)
      if item.operator is "OR"
        currentGroup = subroutine(item.left, previousGroup)
        groups.push currentGroup
        currentGroup and subroutine(item.right, [])
    return

  previousGroup = previousGroup or []
  subroutine item, previousGroup
  groups

createGroups o
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top