问题
Ok here's one at which I've been scratching my head at without great success so far; Sorry in advance for the very long question...
I am using this Lucene Query Parser to parse a string/query which produce this kind of data structure:
// 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"
}
}
}
I need to iterate on that object to obtain the following:
[ [{ field: "field1", term: "val1"},
{ field: "field2", term: "val2"}
],
[{ field: "field3", term: "val3"},
{ field: "field3", term: "val4"}
]
]
If I try to explain this, the idea is to create an array of arrays where each child array are separated by "OR", while each objects inside the child arrays represents the "AND" separated fields; Although I think the code above explains it better than me
Updated code (coffeescript and lo-dash, sorry):
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
This code works, and pretty much do what I want, but rely on the groups array to be declared outside the function (fine), but used as is directly inside the function, which is not quite ideal, but I can live with it.
However, it will duplicate every groups like so:
[ [ {field: "field1", val:val1}, {field: "field2" val:val2} ], [ {field: "field1":val1}, {field: "field2", val:val2} ], ...]
For now I have to use _.uniq(groups) which is an operation I shouldnt have to do, if the above function would return the correct results
Thanks for your help
回答1:
I think this ought to do it:
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
来源:https://stackoverflow.com/questions/23024589/javascript-nested-object-to-multidimensional-array-recursive-function