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:
我使用这个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"
}
}
}
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
如果我试着解释一下,我的想法是创建一个数组数组,其中每个子数组用“OR”分隔,而子数组中的每个对象代表“AND”分隔的字段;虽然我认为上面的代码比我更好地解释了它
Updated code (coffeescript and lo-dash, sorry):
更新的代码(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
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.
这段代码很有用,几乎可以做我想要的,但依赖于groups数组在函数外部声明(精细),但直接在函数内部使用,这不是很理想,但我可以忍受它。
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
现在我必须使用_.uniq(groups)这是一个我不应该做的操作,如果上面的函数会返回正确的结果
Thanks for your help
谢谢你的帮助
1 个解决方案
#1
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
#1
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