向数组推送对象时如何消除多余层级?
jQuery筛选JSON数据出现多余数组层级的原因及修复方法
问题场景
我正在用jQuery读取JSON文件,筛选指定ID的产品到新数组中。JSON结构如下:
[ { "id": "1234", "label": "Product 1", "price": "140" }, { "id": "5678", "label": "Product 2", "price": "199" }, { "id": "9012", "label": "Product 3", "price": "500" } // 更多数据 ]
使用以下代码筛选数据:
const activeProdIDs = [1234, 9012]; let filteredJson = []; $.ajax({ url: dataURL, type: "GET", dataType: "json", success: function (myJson) { activeProdIDs.forEach(function(prodID) { filteredJson.push(myJson.filter(item => item.id == prodID)); }); console.log(filteredJson); }, error: function () { console.log("Something went wrong"); }, });
代码能运行,但返回的数组有多余层级,变成了二维数组:
[ [ { "id": "1234", "label": "Product 1", "price": "140" } ], [ { "id": "9012", "label": "Product 3", "price": "500" } ] // 更多数据 ]
无法直接用filteredJson[0].label访问标签,必须写filteredJson[0][0].label,想知道原因和修复方法。
原因分析
*Array.filter()*方法的返回值本身就是数组——哪怕只匹配到一个元素,它也会把这个元素包裹在数组里返回。你现在用forEach遍历activeProdIDs,每次把filter返回的数组直接push到filteredJson中,自然就形成了二维数组。
修复方案
方案1:用find()替代filter()(推荐)
如果每个产品ID是唯一的,用*Array.find()*更合适——它直接返回第一个匹配的元素(不是数组),没有多余层级:
const activeProdIDs = [1234, 9012]; let filteredJson = []; $.ajax({ url: dataURL, type: "GET", dataType: "json", success: function (myJson) { activeProdIDs.forEach(function(prodID) { // 查找匹配的单个元素 const matchedItem = myJson.find(item => item.id == prodID); // 避免找不到时推入undefined,可根据需求选择是否保留此判断 if (matchedItem) { filteredJson.push(matchedItem); } }); console.log(filteredJson); }, error: function () { console.log("Something went wrong"); }, });
方案2:展开filter()返回的数组
如果一定要用filter(),可以用扩展运算符...把返回数组里的元素逐个推入filteredJson:
activeProdIDs.forEach(function(prodID) { // 展开数组,将内部元素直接添加到filteredJson filteredJson.push(...myJson.filter(item => item.id == prodID)); });
方案3:一次筛选完成(性能最优)
上面两种方法都需要遍历activeProdIDs再遍历myJson,数据量大时效率较低。可以反过来对myJson做一次筛选,判断元素ID是否在目标列表中:
$.ajax({ url: dataURL, type: "GET", dataType: "json", success: function (myJson) { // 把ID转成Set(JSON里id是字符串,所以要转成字符串类型),提高查找效率 const activeIDs = new Set(activeProdIDs.map(id => String(id))); // 一次筛选完成 filteredJson = myJson.filter(item => activeIDs.has(item.id)); console.log(filteredJson); }, error: function () { console.log("Something went wrong"); }, });
内容的提问来源于stack exchange,提问作者MeltingDog
相关产品推荐
相关产品推荐

