http://jsfiddle.net/w4Wqh/1/
正直なところ、正規表現でこれを行う方法があると思います..しかし、私はそれを理解できませんでした。したがって、これは少し醜い文字列操作です。いずれにせよ、これは私が思う正しい軌道に乗るはずです:
function serialize () {
var serialized = {};
$("[name]").each(function () {
var name = $(this).attr('name');
var value = $(this).val();
var nameBits = name.split('[');
var previousRef = serialized;
for(var i = 0, l = nameBits.length; i < l; i++) {
var nameBit = nameBits[i].replace(']', '');
if(!previousRef[nameBit]) {
previousRef[nameBit] = {};
}
if(i != nameBits.length - 1) {
previousRef = previousRef[nameBit];
} else if(i == nameBits.length - 1) {
previousRef[nameBit] = value;
}
}
});
return serialized;
}
console.log(serialize());
簡単な説明。これは、「name」属性を持つものをすべて取得し、それらを反復処理します。反復ごとに、名前を取得して「[」で分割します。これにより、基本的に、オブジェクトを配置する必要があるオブジェクトの深さがわかります。したがって、Person[addresses][work] の場合、Person, addresses], work] を取得します。
次に、トリッキーな部分があります。オブジェクトは常に参照によって渡されるため、シリアル化された変数に「Person」が含まれているかどうかを確認できます。そうでない場合は、それを追加し、値を空のオブジェクトに設定します。これは、より多くのものを保存するために使用するのに十分な汎用性があるか、必要に応じて置き換えられます。通過する必要があるレベルがなくなった場合は、要素の値を取得して、それが持つ参照に割り当てます。それ以外の場合、コードは作成したばかりのものへの参照を取得し、再びループして同じ操作を実行します。したがって、Person[住所][勤務先] については..
- serialized.Person は存在しますか? いいえ。serialized.Person を {} に設定します。これはループの終わりではなく、serialized.Person への参照を previousRef として保存します。
- previousRef.addresses は存在しますか? (serialized.Person.addresses) いいえ。previousRef.addresses を {} に設定します。これはループの終わりではなく、previousRef.addresses への参照を previousRef として格納します。
- 以前のRef.workは存在しますか? (serialized.Person.addresses.work) いいえ。previousRef.work を {} に設定します。待って。これでループは終了です。要素の値に previousRef.work を設定します。