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

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top