访问和更改不可变对象中的嵌套值

时间:2018-12-19 17:59:36

标签: javascript data-structures functional-programming nested immutability

我正在尝试访问嵌套对象和数组,以将所有错误连接到由点.分隔的每个对象键的单个字符串中。我想要 遍历需要它和不需要它的程序,我希望它继续进行下一个键。

我能够通过前两个键进行映射并成功添加点并通过加入空格来通过前两个测试,但是无法通过嵌套对象或数组

  function transformErrors(error) {
  return error.map(value => {
    // console.log("The current iteration is: " + index);
    // console.log("The current element is: " + currElement);

    return value
      .map((currElement, index) => {
        // console.log("The current iteration is: " + index);
        // console.log("The current element is: " + currElement);

        if (index === undefined && index === index) {
          // return index++;
        } else {
          return `${currElement}.`;
        }
      })
      .join(" ");
  });
}

我要通过的测试:

it("should tranform errors", () => {
  // example error object returned from API converted to Immutable.Map
  const errors = Immutable.fromJS({
    name: ["This field is required"],
    age: ["This field is required", "Only numeric characters are allowed"],
    urls: [
      {},
      {},
      {
        site: {
          code: ["This site code is invalid"],
          id: ["Unsupported id"]
        }
      }
    ],
    url: {
      site: {
        code: ["This site code is invalid"],
        id: ["Unsupported id"]
      }
    },
    tags: [
      {},
      {
        non_field_errors: ["Only alphanumeric characters are allowed"],
        another_error: ["Only alphanumeric characters are allowed"],
        third_error: ["Third error"]
      },
      {},
      {
        non_field_errors: [
          "Minumum length of 10 characters is required",
          "Only alphanumeric characters are allowed"
        ]
      }
    ],
    tag: {
      nested: {
        non_field_errors: ["Only alphanumeric characters are allowed"]
      }
    }
  });

  let result = transformErrors(errors);

  assert.deepEqual(result.toJS(), {
    name: "This field is required.",
    age: "This field is required. Only numeric characters are allowed.",
    urls: [
      {},
      {},
      {
        site: {
          code: "This site code is invalid.",
          id: "Unsupported id."
        }
      }
    ],
    url: {
      site: {
        code: "This site code is invalid.",
        id: "Unsupported id."
      }
    },
    tags:
      "Only alphanumeric characters are allowed. Third error. " +
      "Minumum length of 10 characters is required.",
    tag: "Only alphanumeric characters are allowed."
  });
});

当前输出:

{
  "age": "This field is required. Only numeric characters are 
allowed."
  "name": "This field is required."
 "tag": "Map { \"non_field_errors\": List [ \"Only alphanumeric 
characters are allowed\" ] }."
 "tags": "Map {}. Map { \"non_field_errors\": List [ \"Only 
alphanumeric characters are allowed\" ], \"another_error\": List [ 
\"Only alphanumeric characters are allowed\" ], \"third_error\": 
List [ \"Third error\" ] }. Map {}. Map { \"non_field_errors\": List 
[ \"Minumum length of 10 characters is required\", \"Only 
alphanumeric characters are allowed\" ] }."
 "url": "Map { \"code\": List [ \"This site code is invalid\" ], 
\"id\": List [ \"Unsupported id\" ] }."
 "urls": "Map {}. Map {}. Map { \"site\": Map { \"code\": List [ 
\"This site code is invalid\" ], \"id\": List [ \"Unsupported id\" ] 
} }."
}

预期输出:

  "tag": "Only alphanumeric characters are allowed."
  "tags": "Only alphanumeric characters are allowed. Third error. 
 Minumum length of 10 characters is required."
  "url": {
    "site": {
      "code": "This site code is invalid."
      "id": "Unsupported id."
    }
  }
  "urls": [
    {}
    {}
    {
      "site": {
        "code": "This site code is invalid."
        "id": "Unsupported id."
       }
    }
  ]

1 个答案:

答案 0 :(得分:1)

您必须递归遍历所有键/值对:

 // Map & List shall be the Immutable types

 function flattenErrors(errors) {
    let result = Map();
    for(let [key, value] of errors) {
       if(Map.isMap(value))
         value = flattenErrors(value); // the recursive call
       if(List.isList(value) && value.every(entry => typeof entry === "string"))
         value = value.join(". ");
       result = result.set(key, value);
   }
   return result;
 }