多次元配列再帰関数へのJavaScriptネストオブジェクト
-
21-12-2019 - |
質問
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
. 所属していません StackOverflow