从数组创建布尔值、数组和对象的嵌套对象
Create nested object of booleans, arrays and objects from array
我正在尝试创建一个对象来满足 json-logic-js 所需的结构。下面提供了该结构的示例。
源数组由booleans
和strings
组成。字符串只能是 OR
、AND
、NAND
或 NOR
。现在我只使用 OR
和 AND
.
布尔值和字符串数组可能如下所示。这些值是动态的。所以布尔值可以是 true 或 false 以及如上所述的字符串。
const source = [false, "OR", false, "OR", false, "AND", false, "AND", false, "OR", true]
如果这个源数组在 if 语句中,我认为它的分组如下:
(false || false || (false && false && false) || true) // true
我希望输出满足 json-logic-js JS 包的以下对象:
const result = {
'or': [
false,
false,
{
'and': [
false,
false,
false,
]
},
true,
]
}
我已经尝试过递归函数并一直在使用 .reduce() 方法,但仍然无法找到解决方案。当我遍历源数组时,我很难创建对象。我在 SO 上搜索了类似的答案,但 none 似乎想要与我相同的结果对象结构。
尝试以下解决方案。希望代码或多或少是 self-explanatory:
function process(arr) {
const isBool = (x) => x === true || x === false;
const prec = (x) => -["AND", "OR"].indexOf(x);
// Convert infix -> postfix
const postfix = [];
const ops = [];
for (const x of arr) {
if (!isBool(x)) {
const prev = ops[ops.length - 1];
if (prev === undefined || prec(x) > prec(prev)) {
ops.push(x);
} else {
while (ops.length > 0 && prec(x) < prec(ops[ops.length - 1])) {
postfix.push(ops.pop());
}
ops.push(x);
}
} else {
postfix.push(x);
}
}
postfix.push(...ops.reverse());
// Convert postfix -> output format
const stack = [];
for (const x of postfix) {
if (!isBool(x)) {
const op = x.toLowerCase();
const prevs = [stack.pop(), stack.pop()];
const obj = prevs.find((y) => !isBool(y) && y.hasOwnProperty(op));
if (obj !== undefined) {
const other = prevs.find((y) => y !== obj);
obj[op].push(other);
stack.push(obj);
} else {
stack.push({
[op]: prevs,
});
}
} else {
stack.push(x);
}
}
return stack[0];
}
console.log(JSON.stringify(process([false, "OR", false, "OR", false, "AND", false, "AND", false, "OR", true]), null, 2));
我正在尝试创建一个对象来满足 json-logic-js 所需的结构。下面提供了该结构的示例。
源数组由booleans
和strings
组成。字符串只能是 OR
、AND
、NAND
或 NOR
。现在我只使用 OR
和 AND
.
布尔值和字符串数组可能如下所示。这些值是动态的。所以布尔值可以是 true 或 false 以及如上所述的字符串。
const source = [false, "OR", false, "OR", false, "AND", false, "AND", false, "OR", true]
如果这个源数组在 if 语句中,我认为它的分组如下:
(false || false || (false && false && false) || true) // true
我希望输出满足 json-logic-js JS 包的以下对象:
const result = {
'or': [
false,
false,
{
'and': [
false,
false,
false,
]
},
true,
]
}
我已经尝试过递归函数并一直在使用 .reduce() 方法,但仍然无法找到解决方案。当我遍历源数组时,我很难创建对象。我在 SO 上搜索了类似的答案,但 none 似乎想要与我相同的结果对象结构。
尝试以下解决方案。希望代码或多或少是 self-explanatory:
function process(arr) {
const isBool = (x) => x === true || x === false;
const prec = (x) => -["AND", "OR"].indexOf(x);
// Convert infix -> postfix
const postfix = [];
const ops = [];
for (const x of arr) {
if (!isBool(x)) {
const prev = ops[ops.length - 1];
if (prev === undefined || prec(x) > prec(prev)) {
ops.push(x);
} else {
while (ops.length > 0 && prec(x) < prec(ops[ops.length - 1])) {
postfix.push(ops.pop());
}
ops.push(x);
}
} else {
postfix.push(x);
}
}
postfix.push(...ops.reverse());
// Convert postfix -> output format
const stack = [];
for (const x of postfix) {
if (!isBool(x)) {
const op = x.toLowerCase();
const prevs = [stack.pop(), stack.pop()];
const obj = prevs.find((y) => !isBool(y) && y.hasOwnProperty(op));
if (obj !== undefined) {
const other = prevs.find((y) => y !== obj);
obj[op].push(other);
stack.push(obj);
} else {
stack.push({
[op]: prevs,
});
}
} else {
stack.push(x);
}
}
return stack[0];
}
console.log(JSON.stringify(process([false, "OR", false, "OR", false, "AND", false, "AND", false, "OR", true]), null, 2));