如何将jQuery serializeArray()结果转换为按引擎分组的JSON数组
问题:将serializeArray结果重组为按引擎分组的数组
我使用jQuery的serializeArray()方法成功收集了引擎表单的信息,但需要将这些数据整理成一个数组,让每个“引擎”作为新数组中的独立项(如引擎1、引擎2)。以下是生成表单的PHP循环代码,以及当前serializeArray()的输出结果,请问如何将该输出转换为可遍历每个引擎项的JSON数组?
原表单代码
<form id="engine_data"> <? foreach ($listing['engines'] as $k => $e) { ?> <div id="engines_cont" > <input type="hidden" name="engine_number" value="<?= $e['engine_no'] ?>" /> <table class="info_table engine_edit"> <colgroup> <col span="1"> <col span="1" style="width: 100%;"> </colgroup> <tbody> <tr> <td class="cell_label">MAKE</td> <td class="cell_info"><input name="engine_make" type="text" placeholder="Engine Make" value="<?= $e['engine_make'] ?>"></td> </tr> <tr> <td class="cell_label">ENGINE TIME</td> <td class="cell_info"><input name="engine_time" type="text" placeholder="Engine Time" value="<?= $e['engine_time'] ?>"></td> </tr> <tr> <td class="cell_label">ENGINE TBO</td> <td class="cell_info"><input name="engine_tbo" type="text" placeholder="Engine TBO" value="<?= $e['engine_tbo'] ?>"></td> </tr> <tr> <td class="cell_label">ENGINE NOTES</td> <td class="cell_info"><input name="engine_notes" type="text" placeholder="Engine Notes" value="<?= $e['engine_notes'] ?>"></td> </tr> </tbody> </table> </div> <? } ?> </form>
当前serializeArray()输出
[ { "name": "engine_number", "value": "1" }, { "name": "engine_make", "value": "P&W" }, { "name": "engine_time", "value": "1200" }, { "name": "engine_tbo", "value": "2000" }, { "name": "engine_notes", "value": "Great engine in good condition" }, { "name": "engine_number", "value": "2" }, { "name": "engine_make", "value": "P&W" }, { "name": "engine_time", "value": "1500" }, { "name": "engine_tbo", "value": "2200" }, { "name": "engine_notes", "value": "Great engine in good condition" } ]
解决方案
方法一:修改表单字段命名(推荐)
直接修改表单中input的name属性,采用数组式命名,这样serializeArray()会自动生成结构化的数组,无需额外前端处理,后端解析也更方便。
修改PHP循环中的字段name:
<form id="engine_data"> <? foreach ($listing['engines'] as $k => $e) { ?> <div id="engines_cont" > <!-- 用engines[$k]分组每个引擎的字段 --> <input type="hidden" name="engines[<?= $k ?>][engine_number]" value="<?= $e['engine_no'] ?>" /> <table class="info_table engine_edit"> <colgroup> <col span="1"> <col span="1" style="width: 100%;"> </colgroup> <tbody> <tr> <td class="cell_label">MAKE</td> <td class="cell_info"><input name="engines[<?= $k ?>][engine_make]" type="text" placeholder="Engine Make" value="<?= $e['engine_make'] ?>"></td> </tr> <tr> <td class="cell_label">ENGINE TIME</td> <td class="cell_info"><input name="engines[<?= $k ?>][engine_time]" type="text" placeholder="Engine Time" value="<?= $e['engine_time'] ?>"></td> </tr> <tr> <td class="cell_label">ENGINE TBO</td> <td class="cell_info"><input name="engines[<?= $k ?>][engine_tbo]" type="text" placeholder="Engine TBO" value="<?= $e['engine_tbo'] ?>"></td> </tr> <tr> <td class="cell_label">ENGINE NOTES</td> <td class="cell_info"><input name="engines[<?= $k ?>][engine_notes]" type="text" placeholder="Engine Notes" value="<?= $e['engine_notes'] ?>"></td> </tr> </tbody> </table> </div> <? } ?> </form>
此时调用$('#engine_data').serializeArray(),得到的结果会自动按引擎分组,再转成对象数组即可:
const formData = $('#engine_data').serializeArray(); const engines = {}; formData.forEach(item => { // 解析name中的分组和字段名 const [, index, field] = item.name.match(/engines\[(\d+)\]\[(\w+)\]/); if (!engines[index]) engines[index] = {}; engines[index][field] = item.value; }); // 转成目标数组 const enginesArray = Object.values(engines);
最终enginesArray就是每个引擎为独立项的数组。
方法二:前端处理现有serializeArray结果
如果无法修改表单代码,可以遍历现有serializeArray()的结果,按engine_number分割分组:
const rawData = $('#engine_data').serializeArray(); const engines = []; let currentEngine = {}; rawData.forEach(item => { // 遇到engine_number时,将当前引擎存入数组并新建对象 if (item.name === 'engine_number') { if (Object.keys(currentEngine).length > 0) { engines.push(currentEngine); } currentEngine = { [item.name]: item.value }; } else { // 其他字段加入当前引擎对象 currentEngine[item.name] = item.value; } }); // 加入最后一个引擎 if (Object.keys(currentEngine).length > 0) { engines.push(currentEngine); } // 此时engines就是目标数组 console.log(engines);
运行后得到的结果:
[ { "engine_number": "1", "engine_make": "P&W", "engine_time": "1200", "engine_tbo": "2000", "engine_notes": "Great engine in good condition" }, { "engine_number": "2", "engine_make": "P&W", "engine_time": "1500", "engine_tbo": "2200", "engine_notes": "Great engine in good condition" } ]
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

