Objeto anidado de Javascript a función recursiva de matriz multidimensional
-
21-12-2019 - |
Pregunta
Ok, aquí hay uno en el que me he estado rascando la cabeza sin gran éxito hasta ahora;Perdón de antemano por la pregunta tan larga...
estoy usando esto Analizador de consultas de Lucene para analizar una cadena/consulta que produce este tipo de estructura de datos:
// 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"
}
}
}
Necesito iterar sobre ese objeto para obtener lo siguiente:
[ [{ field: "field1", term: "val1"},
{ field: "field2", term: "val2"}
],
[{ field: "field3", term: "val3"},
{ field: "field3", term: "val4"}
]
]
Si trato de explicar esto, la idea es crear una matriz de matrices donde cada matriz secundaria esté separada por "O", mientras que cada objeto dentro de las matrices secundarias representa los campos separados por "Y";Aunque creo que el código anterior lo explica mejor que yo.
Código actualizado (guión de café y lo-dash, Lo siento):
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
Este código funciona y prácticamente hace lo que quiero, pero confío en el groups
La matriz se declarará fuera de la función (bien), pero se usará tal como está directamente dentro de la función, lo cual no es del todo ideal, pero puedo vivir con ello.
Sin embargo, duplicará todos los grupos de esta manera:
[ [ {field: "field1", val:val1}, {field: "field2" val:val2} ], [ {field: "field1":val1}, {field: "field2", val:val2} ], ...]
Por ahora tengo que usar _.uniq(groups)
que es una operación que no debería tener que hacer, si la función anterior arrojara los resultados correctos
Gracias por tu ayuda
Solución
Creo que esto debería ser suficiente:
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