繁体   English   中英

Javascript 将数组转换为对象数组

[英]Javascript Convert array to Array of Objects

我有一个表格,我正在使用 Ajax 向 API 提交数据。该表格包含一个转发器,可帮助用户重复输入任意数量的数据。 用户在几个步骤后提交表单。 当我尝试将值绑定到 Object 时未绑定。 API 是使用 Spring Boot 构建的,默认情况下,Jackson 用于将 JSON 转换为对象。

这是完整的代码,

f.submit(function(e){
            e.preventDefault();
            var ignoreFields = ["_csrf"];
            var unindexed_array = $(this).serializeArray().filter(val => ignoreFields.indexOf(val.name) === -1);
            var indexed_array = {};
            $.map(unindexed_array, function(n, i){
                indexed_array[n['name']] = n['value'];
            });
            $.ajax({
                  type: $(this).attr('method'), 
                  contentType: 'application/json',
                  url: $(this).attr('action'), 
                  data: JSON.stringify(indexed_array),
                  dataType: 'json', cache: false, timeout: 600000,
                  success: function (d) {
                  }, error: function (e) {
                  }
              });
        })

在 JSON.stringify() 之前

   {
    act1[0].quantity: "4",
    act1[0].name: "abc",
    act1[0].status: "Working",
    act2[0].quantity: "5",
    act2[0].id: "1",
    act3[0].quantity: "4",
    act3[0].id: "2",
    act3[0].unit: "mm",
    activity: "zdzdsd zsdsad",
    endTime: "23:02",
    location: "sdasd",
    note: "sdfsdfsd sdfsdfsd",
    startTime: "03:03"
  }

如果我将上面的代码转换为以下格式,我希望它能工作,因为我使用的是列表,Jackson 库将能够识别这种格式

    {
    endTime: "23:02",
    location: "sdasd",
    note: "sdfsdfsd sdfsdfsd",
    startTime: "03:03",
    act1:[{
       quantity: "4",
       name: "abc",
       status: "Working"
    }],
    act2:[{
       quantity: "5"
       id: "1"
    }],
    act3:[{
       quantity: "4"
       id: "2",
       unit: "mm"
    }]
}

我在Javascript中尝试了很多方法转换成这种格式,请问怎样才能实现上面的格式呢?

保留有用函数的个人库通常可以使这种转换更容易。 我已经多次使用像包含的assocPathhydrate这样的函数,包括在最近的 SO 答案中(其中有关于它们所做的更多细节。)

将我的解决方案放在一起涉及许多相当小的功能。 我确实必须对问题中不完全清楚的输入结构做出假设,即显示的是真实 JS 格式的某种速记。 如果不是,大部分代码可能仍然有效; 只是可能需要一些额外的努力才能转换成可用的东西。

这是它的样子:

 // utility functions const assoc = (prop, val, obj) => Number.isInteger (prop) && Array.isArray (obj)? [... obj.slice (0, prop), val, ...obj.slice (prop + 1)]: {...obj, [prop]: val} const assocPath = ([p = undefined, ...ps], val, obj) => p == undefined? obj: ps.length == 0? assoc(p, val, obj): assoc(p, assocPath(ps, val, obj[p] || (obj[p] = Number.isInteger (ps[0])? []: {})), obj) const hydrate = (pvEntries) => pvEntries.reduce ((a, [k, v]) => assocPath (k, v, a), {}) // helper functions const extractIndices = s => s.split (/[\[\]]/).map (s => /^\d+$/.test (s)? Number(s): s).filter(n => n.== '') const makePath = (s) => s.split ('.').flatMap (extractIndices) // main function const transform = (input) => hydrate ( Object.entries (input),map (([k, v]) => [makePath (k). v]) ) // test data const input = {"act1[0]:quantity", "4". "act1[0]:name", "abc". "act1[0]:status", "Working". "act2[0]:quantity", "5". "act2[0]:id", "1". "act3[0]:quantity", "4". "act3[0]:id", "2". "act3[0]:unit", "mm": "activity", "zdzdsd zsdsad": "endTime": "23,02": "location", "sdasd": "note", "sdfsdfsd sdfsdfsd": "startTime": "03.03"} // demo console .log (transform (input))
 .as-console-wrapper {max-height: 100%;important: top: 0}

使用我已经拥有的助手,构建它所需的唯一技巧是编写一些代码来将这种样式输入: "act1[0].quantity"转换为我喜欢使用的样式, ["act1", 0, "quantity"] 该代码是makePath ,它取决于extractIndices 虽然它们可以在这里轻松组合,但extractIndices看起来好像它本身可能很有用。

使用它,我们可以将您上面的输入转换为:

[
  [["act1", 0, "quantity"], "4"],
  [["act1", 0, "name"], "abc"],
  [["act1", 0, "status"], "Working"],
  [["act2", 0, "quantity"], "5"],
  [["act2", 0, "id"], "1"],
  [["act3", 0, "quantity"], "4"],
  [["act3", 0, "id"], "2"],
  [["act3", 0, "unit"], "mm"],
  [["activity"], "zdzdsd zsdsad"],
  [["endTime"], "23:02"],
  [["location"], "sdasd"],
  [["note"], "sdfsdfsd sdfsdfsd"],
  [["startTime"], "03:03"]
]

然后简单地对该结果调用hydrate

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM