假设我有一个表单,我想检查表单中声明了哪些输入,所以我做了这样的事情:
let inputs = {};
['first_name', 'last_name', ...].forEach(name => {
let input = document.querySelector(`input[name="${name}"]`);
if (input !== undefined)
inputs = Object.assign(inputs, {[input.getAttribute('name')]: input.value});
}
在这种情况下,到目前为止一直很好。
但是如果有一些名为['name.first', 'name.last']
的输入怎么办?然后,它会将数据存储到这样的对象:
{name.first: '...', name.last: '...'}.
而不是这样:(这是我想要的结果)
{
name: {
first: '...',
last: '...'
}
}
如何告诉JavaScript将其解析为对象路径而不是键字符串?
答案 0 :(得分:1)
我会使用自定义分配功能。
对象可以使用任何字符串作为键,因此“a.b”有效。
以下是assign函数的示例:
function assign(obj, key, value) {
let keys = key.split(".");
let last = keys.pop();
keys.forEach(key => {
if(!obj[key])
obj[key] = {};
obj = obj[key];
});
obj[last] = value;
}
let obj = {};
assign(obj, "name.first", "hey");
assign(obj, "name.last", "bye");
console.log(obj);
Bonus recomendation:如果您对所有表单使用相同的格式,则可以将其用作全局表单处理程序。
function formHandler(form) {
let obj = {};
form.querySelectorAll("input, select").forEach(elem => assign(obj, elem.name, elem.value));
return obj;
}
答案 1 :(得分:0)
那样的东西?
libswiftCore.dylib`function signature specialization <preserving fragile attribute, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt, flags : Swift.UInt32) -> Swift.Never:
0x100385174 <+0>: stp x26, x25, [sp, #-80]!
0x100385178 <+4>: stp x24, x23, [sp, #16]
0x10038517c <+8>: stp x22, x21, [sp, #32]
0x100385180 <+12>: stp x20, x19, [sp, #48]
0x100385184 <+16>: stp x29, x30, [sp, #64]
0x100385188 <+20>: add x29, sp, #64 ; =64
0x10038518c <+24>: mov x19, x6
0x100385190 <+28>: mov x20, x5
0x100385194 <+32>: mov x21, x4
0x100385198 <+36>: mov x22, x3
0x10038519c <+40>: mov x23, x2
0x1003851a0 <+44>: mov x24, x1
0x1003851a4 <+48>: mov x25, x0
0x1003851a8 <+52>: adr x8, #936952 ; protocol descriptor for Swift.CVarArg + 88
0x1003851ac <+56>: nop
0x1003851b0 <+60>: add x0, x8, #16 ; =16
0x1003851b4 <+64>: movz w1, #0x28
0x1003851b8 <+68>: orr w2, wzr, #0x7
0x1003851bc <+72>: bl 0x1003854a0 ; rt_swift_allocObject
0x1003851c0 <+76>: mov x8, x0
0x1003851c4 <+80>: stp x22, x21, [x8, #16]
0x1003851c8 <+84>: strb w20, [x8, #32]
0x1003851cc <+88>: str w19, [x8, #36]
0x1003851d0 <+92>: adr x3, #241008 ; partial apply forwarder for Swift.(_fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt, flags : Swift.UInt32) -> Swift.Never).(closure #2)
0x1003851d4 <+96>: nop
0x1003851d8 <+100>: mov x0, x25
0x1003851dc <+104>: mov x1, x24
0x1003851e0 <+108>: mov x2, x23
0x1003851e4 <+112>: mov x4, x8
0x1003851e8 <+116>: bl 0x100278b70 ; function signature specialization <preserving fragile attribute, Arg[1] = [Closure Propagated : reabstraction thunk helper from @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> () to @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> (@out ()), Argument Types : [@callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> ()]> of generic specialization <preserving fragile attribute, ()> of Swift.StaticString.withUTF8Buffer <A> ((Swift.UnsafeBufferPointer<Swift.UInt8>) -> A) -> A
-> 0x1003851ec <+120>: brk #0x1 //Error message here
答案 2 :(得分:0)
使用与其他答案(拆分,测试和创建)相同的原则来创建路径,但演示了过滤示例的替代方法(如我的评论中所述)。
const wanted = ['name.first', 'name.second', 'name.last'];
const result = Array.from(document.querySelectorAll('input'))
.filter(input => wanted.includes(input.name))
.reduce((a, input) => {
const paths = input.name.split('.');
const key = paths.pop();
let current = a;
paths.forEach(path => current = current[path] ?
current[path] :
current[path] = Object.create(null));
current[key] = input.value;
return a;
}, Object.create(null));
console.log(result);
<input name="name.first" value="Eliya" />
<input name="name.middle" value="Wibble" />
<input name="name.last" value="Cohen" />