解析嵌套对象不会使用 javascript

时间:2021-03-22 17:50:30

标签: javascript nested-loops

我正在尝试解析以下格式的嵌套对象:

const obj = {
  "and": [
      {
        "!=": [
          {
            "var": "name"
          },
          "name1"
        ]
      },
      {
        "in": [
          {
            "var": "hobbies"
          },
          "jogging, video games"
        ]
      }
    ]
};

我创建了一个函数来解析它:

const isOperatorCode(code) => {
  const allowedOperatorCodes = ['in', '<=', '!=', '=='];
  return allowedOperatorCodes.includes(code);
}

const parseObject = (arg, result={}) => {
  if (arg === undefined || arg === null) return arg;

  if (arg.constructor === Object && Object.keys(arg).length) {
    for (const key in arg) {
      const value = arg[key];
      if (key === 'and' || key === 'or' || key === '!') {
        result.operator = key === '!' ? 'not' : key;
        result.operands = [];
        return parseObject(value, result);
      }
      if (isOperatorCode(key)) {
        const newItem = {
          operator: key,
          attribute: value[0].var,
          value: value[1]
        }

        result.operands.push(newItem);

      }
    }
  }

  if(Array.isArray(arg) && arg.length) {
    for (const k of arg) {
      return parseObject(k, result);
    }
  }
  return result;
  
}

我在执行函数时得到了这个结果:

{"operator":"and","operands":[{"operator":"!=","attribute":"name","value":"name1"}]}

it should be:

{"operator":"and","operands":[{"operator":"!=","attribute":"name","value":"name1"}, {"operator":"in","attribute":"hobbies","value":"sport, video games"}]}

我知道数组不会保留元素的踪迹以继续循环遍历不同的项目。任何想法或建议来跟踪数组元素并在它们上循环?

3 个答案:

答案 0 :(得分:2)

return parseObject(k, result); 停止执行循环,因此您只会获得第一项。

for (const k of arg) {
  return parseObject(k, result); // return breaks out of the loop. Only processes the first item.
}

也许这更有意义?

  return args.map(k => parseObject(k, result)); // process all entries, return an array.

答案 1 :(得分:2)

如果你只在最后return,你会得到预期的结果。

const obj = {
  "and": [{
    "!=": [{
      "var": "name"
    }, "name1"]
  }, {
    "in": [{
      "var": "hobbies"
    }, "jogging, video games"]
  }]
};

const isOperatorCode = (code) => {
  const allowedOperatorCodes = ['in', '<=', '!=', '=='];
  return allowedOperatorCodes.includes(code);
}

const parseObject = (arg, result = {}) => {
  if (arg === undefined || arg === null) return arg;
  if (arg.constructor === Object && Object.keys(arg).length) {
    for (const key in arg) {
      const value = arg[key];
      if (key === 'and' || key === 'or' || key === '!') {
        result.operator = key === '!' ? 'not' : key;
        result.operands = [];
        parseObject(value, result);
      }
      if (isOperatorCode(key)) {
        const newItem = {
          operator: key,
          attribute: value[0].var,
          value: value[1]
        }
        result.operands.push(newItem);
      }
    }
  }
  if (Array.isArray(arg) && arg.length) {
    for (const k of arg) {
      parseObject(k, result);
    }
  }
  return result;
}

console.log(parseObject(obj));
.as-console-wrapper { top: 0; max-height: 100% !important; }

答案 2 :(得分:2)

您可以采用递归方法查看以 var 为键的对象。

const
    convert = object => {
        if (!object || typeof object !== 'object') return object;
        const [operator, values] = Object.entries(object)[0];

        return values[0] && typeof values[0] === 'object' && 'var' in values[0]
            ? { operator, attribute: values[0].var, value: values[1] }
            : { operator, operands: values.map(convert) };
    },
    object = { and: [{ "!=": [{ var: "name" }, "name1"] }, { in: [{ var: "hobbies" }, "jogging, video games"] }] },
    result = convert(object);

   console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }