как отфильтровать свойства вложенных объектов в javascript и распечатать новый объект

#javascript #object #filter

Вопрос:

У меня есть объект, который построен таким образом, он динамичен, поэтому я не знаю, сколько будет вложенных объектов и внешних ключей объекта.Единственными известными ключами снаружи являются «ставки», а внутри (необходимые свойства).

 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://local:4000/examples/pbjs_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=5757398amp;cch=36757096amp;code=37127675amp;l=3…tcGlkPUVERkNGMDY5LTA2ODctNDAxQy04NkMwLTIzQjNFNzI1MzdGNiZwYXNzYmFjaz0w_url='></script></span> <!-- PubMatic Ad Ends -->",
        "adUrl": "https://aktrack.pubmatic.com/AdServer/AdDisplayTrackerServlet?operId=1amp;pubId…local:4000/examples/pbjs_partial_refresh_example.htmlamp;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"
        }
      }
    ]
  }
}
  
 

и я хочу очистить от внутреннего объекта все ключи и значения, кроме (cpm, участник торгов, adUnitCode)
, и вернуть новый объект только с этими свойствами

Я пытаюсь понять, что я собираюсь сделать до сих пор

  for(let propName in data) {
    if(data.hasOwnProperty(propName)) {
        let propValue = data[propName];
        for(var insideProp in propValue.bids) {
          if(propValue.bids.hasOwnProperty(insideProp)) {
              let insideValue=propValue.bids[insideProp]
              for(let insideLvl2 in insideValue) {
                   if(insideLvl2!=='cpm'){
                     insideValue.insideLvl2=null;
                     console.log(insideValue.insideLvl2);
                   }
              }
               
             }
          
        
        }
    }
}


 

спасибо за помощь

Ответ №1:

Если вам нужен cpm, bidder, adUnitCode только результирующий объект, вы можете легко сделать это с помощью Object.entries, reduce и map

Живая демонстрация

Демонстрация Codesandbox

 const result = Object.entries(data).reduce((acc, [k, v]) => {
  acc[k] = {
    ...v,
    bids: v.bids.map(({ cpm, bidder, adUnitCode }) => ({
      cpm,
      bidder,
      adUnitCode,
    })),
  };
  return acc;
}, {});
 

ОТРЕДАКТИРОВАНО: если вы хотите вернуть cpm=null , если cpm в самом объекте нет свойства, вы можете сделать так:

 Object.entries(data).reduce((acc, [k, v]) => {
  acc[k] = {
    ...v,
    bids: v.bids.map(({ cpm = null, bidder = null, adUnitCode = null }) => ({   // change
      cpm,
      bidder,
      adUnitCode,
    })),
  };
  return acc;
}, {})
 
 let data = {
  "/9968336/header-bid-tag1": {
    bids: [
      {
        bidderCode: "casale",
        statusMessage: "Bid returned empty or error response",
        adId: "108c0ba49d",
        requestTimestamp: 1444844944130,
        responseTimestamp: 1444844944223,
        timeToRespond: 93,
        adUnitCode: "/19968336/header-bid-tag1",
        bidder: "casale",
      },
    ],
  },
};

const result = Object.entries(data).reduce((acc, [k, v]) => {
  acc[k] = {
    ...v,
    bids: v.bids.map(({ cpm = null, bidder = null, adUnitCode = null }) => ({
      cpm,
      bidder,
      adUnitCode,
    })),
  };
  return acc;
}, {});

console.log(result); 

Комментарии:

1. спасибо за это, это хорошо, но, как я удостоверяюсь, что значения во внутреннем объекте присутствуют, и сделать, например, если statment:if(cpm not found do x)

2. расскажите мне весь сценарий с примером и каким должен быть ваш ожидаемый результат?

3. внутренний объект (последний lvl является динамическим, поэтому в некоторых случаях некоторые параметры могут не существовать, например: ` let data= { «/9968336/header-bid-tag1»: { «ставки»: [ { «bidderCode»: «casale», «statusMessage»: «Ставкавозвращенный пустой или ошибочный ответ», «AdID»: «108c0ba49d», «RequestTimestamp»: 1444844944130, «responseTimestamp»: 1444844944223, «timeToRespond»: 93, «adUnitCode»: «/19968336/header-bid-tag1», «участник торгов»: «casale» }` в этом случаеЯ хочу вернуть тот же объект, но cpm= null @decpk

4. @Romka отредактировал код, посмотрите

5. спасибо, что он работает хорошо:>