جافا سكريبت كائن متداخل لوظيفة متكررة متعددة الأبعاد
-
21-12-2019 - |
سؤال
حسنًا، هذا هو السؤال الذي كنت أخدش فيه رأسي دون أن أحقق نجاحًا كبيرًا حتى الآن؛آسف مقدما على السؤال الطويل جدا ...
أنا أستخدم هذا محلل الاستعلام لوسين لتحليل سلسلة/استعلام ينتج هذا النوع من بنية البيانات:
// 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"؛على الرغم من أنني أعتقد أن الكود أعلاه يشرح ذلك أفضل مني
رمز محدث (com.coffeescript و لو اندفاعة, ، آسف):
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