JavaScript如何过滤嵌套对象属性并生成仅含指定字段的新对象
动态结构JavaScript对象属性过滤实现
需求说明
我有一个结构动态的JavaScript对象,外层键的数量和名称均不固定,仅能确定每个外层键对应的子对象下存在bids字段,其值为对象数组。我需要过滤bids数组内的每个对象,仅保留cpm、bidder、adUnitCode三个属性,移除其余所有属性,最终返回处理后的新对象。
示例数据结构
let data= { "/9968336/header-bid-tag-0": { "bids": [ { "bidderCode": "appnexus", "width": 300, "height": 250, "statusMessage": "Bid available", "adId": "7a53a9d3", "creative_id": 29681110, "cpm": 0.5, "adUrl": "https://nym1.ib.adnxs.com/ab?e=wqT_3QLzBKBqAgAAAgDWAAUIkav6sAUQucfc0v-nzQcYj…r=http%3A%2F%2Flocal%3A4000%2Fexamples%2Fpbjs_partial_refresh_example.html", "requestTimestamp": 1444844944095, "responseTimestamp": 1444844944180, "timeToRespond": 85, "adUnitCode": "/19968336/header-bid-tag-0", "bidder": "appnexus", "usesGenericKeys": true, "size": "300x250", "adserverTargeting": { "hb_bidder": "appnexus", "hb_adid": "7a53a9d3", "hb_pb": "0.50" } },{ "bidderCode": "pubmatic", "width": "300", "height": "250", "statusMessage": "Bid available", "adId": "1139e34e14", "adSlot": "39620189@300x250", "cpm": 1, "ad": "<span class=\"PubAPIAd\"><script src='https://ad.turn.com/server/ads.js?pub=5757398&cch=36757096&code=37127675&l=3…tcGlkPUVERkNGMDY5LTA2ODctNDAxQy04NkMwLTIzQjNFNzI1MzdGNiZwYXNzYmFjaz0w_url='></script></span> <!-- PubMatic Ad Ends -->", "adUrl": "https://aktrack.pubmatic.com/AdServer/AdDisplayTrackerServlet?operId=1&pubId…local%3A4000%2Fexamples%2Fpbjs_partial_refresh_example.html&lpu=hotels.com", "dealId": "", "requestTimestamp": 1444844944105, "responseTimestamp": 1444844944354, "timeToRespond": 249, "adUnitCode": "/19968336/header-bid-tag-0", "bidder": "pubmatic", "usesGenericKeys": true, "size": "300x250", "adserverTargeting": { "hb_bidder": "pubmatic", "hb_adid": "1139e34e14", "hb_pb": "1.00" } }, { "bidderCode": "rubicon", "width": "300", "height": "250", "statusMessage": "Bid available", "adId": "130d3b0d9b", "cpm": 0.795995, "ad": "<scri...pt>", "ad_id": "3161645", "sizeId": "15", "requestTimestamp": 1444844944116, "responseTimestamp": 1444844944396, "timeToRespond": 280, "adUnitCode": "/19968336/header-bid-tag-0", "bidder": "rubicon", "usesGenericKeys": true, "size": "300x250", "adserverTargeting": { "hb_bidder": "rubicon", "hb_adid": "130d3b0d9b", "hb_pb": "0.50" } } ] }, "/9968336/header-bid-tag1": { "bids": [ { "bidderCode": "casale", "width": 0, "height": 0, "statusMessage": "Bid returned empty or error response", "adId": "108c0ba49d", "requestTimestamp": 1444844944130, "responseTimestamp": 1444844944223, "timeToRespond": 93, "cpm": 6, "adUnitCode": "/19968336/header-bid-tag1", "bidder": "casale" }, { "bidderCode": "openx", "width": "728", "height": "90", "statusMessage": "Bid available", "adId": "14d7f9208f", "ad_id": "537161420", "cpm": 1.717, "ad": "<iframe src=...tame>", "requestTimestamp": 1444844944130, "responseTimestamp": 1444844944490, "timeToRespond": 360, "adUnitCode": "/19968336/header-bid-tag1", "bidder": "openx", "usesGenericKeys": true, "size": "728x90", "adserverTargeting": { "hb_bidder": "openx", "hb_adid": "14d7f9208f", "hb_pb": "1.50" } } ] } }
原有代码问题
你编写的代码无法实现需求的核心原因有两个:
- 使用
insideValue.insideLvl2是访问名为insideLvl2的固定属性,不是访问变量insideLvl2对应的动态属性名,应该用insideValue[insideLvl2]写法 - 直接给属性赋值为
null并没有真正移除属性,且只判断了排除cpm,没有处理另外两个需要保留的字段
正确实现方案
方案1:不修改原对象,返回全新对象(推荐,避免污染原始数据)
function filterBidsData(originData) { // 定义需要保留的字段列表 const keepFields = ['cpm', 'bidder', 'adUnitCode']; const result = {}; // 遍历外层所有动态键 for (const outerKey in originData) { if (originData.hasOwnProperty(outerKey)) { const outerItem = originData[outerKey]; // 处理bids数组,仅保留指定字段 const filteredBids = outerItem.bids.map(bid => { const newBid = {}; keepFields.forEach(field => { if (bid.hasOwnProperty(field)) { newBid[field] = bid[field]; } }); return newBid; }); // 赋值到结果对象,保持外层结构不变 result[outerKey] = { bids: filteredBids }; } } return result; } // 调用方式 const processedData = filterBidsData(data);
方案2:直接修改原对象(不需要保留原始数据时可使用)
const keepFields = ['cpm', 'bidder', 'adUnitCode']; for (const outerKey in data) { if (data.hasOwnProperty(outerKey)) { const bids = data[outerKey].bids; bids.forEach(bid => { // 遍历bid的所有属性,删除不在保留列表里的字段 for (const key in bid) { if (bid.hasOwnProperty(key) && !keepFields.includes(key)) { delete bid[key]; } } }) } }
两种方案都兼容外层键动态的场景,也能确保bids数组里的对象仅保留指定的三个属性。
内容的提问来源于stack exchange,提问作者Romka
相关产品推荐
相关产品推荐

