[英]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中尝试了很多方法转换成这种格式,请问怎样才能实现上面的格式呢?
保留有用函数的个人库通常可以使这种转换更容易。 我已经多次使用像包含的assocPath
和hydrate
这样的函数,包括在最近的 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.