簡體   English   中英

如何使用純Javascript訪問最深層的雙重嵌套數組/對象?

[英]How to access innermost levels of doubly nested arrays/objects using plain Javascript?

我懷疑答案很簡單,但是我搜索了該網站和其他網站,但沒有找到一個。 我有一個雙重嵌套的數據結構,無法弄清楚如何在最內層進行迭代。 我猜想它可能涉及到forEach()或map()方法,但我嘗試過的任何方法都沒有。

背景:我已經簡化了該問題的數據。 數據(粘貼在下面)存儲在包含2個零售商店對象的數組中。 每個商店對象都有一個visits屬性,其值是一組visit對象。 每次訪問(對象)都由訪問日期標識(假設在日期B最多可以有1次訪問存儲A)。 每個訪問對象都包含一個values屬性,其值是該訪問時進行的交易(購買或退貨)數組。 在實際的完整數據中,每個商店的每個日期的交易數量變化很大。

我需要幫助的任務:(a)將屬性key重命名為visitDate ,(b)將屬性values重命名為transactions ,(c)刪除8個冗余屬性(從storeIDstoreVisitDate ),但保留actiondollarAmount屬性,以及(d)將屬性dollarAmount重命名為dollars

非常感激任何的幫助。 謝謝。

 [
   {
     "storeName": "Ye Olde Candy Shoppe",
     "address": "1313 Vampire Lane, Cityville NY 99999",
     "zipCode": "99999",
     "storeSize": "large",
     "visits": [
       {
         "key": "5/3/12",
         "values": [
           {
             "storeID": "53454447",
             "storeName": "Ye Olde Candy Shoppe",
             "city": "Cityville",
             "building": "1313",
             "street": "Vampire Lane",
             "zipcode": "99999",
             "storeSize": "large",
             "storeVisitDate": "5/3/12",
             "action": "Return",
             "dollarAmount": "65.43"
           },
           {
             "storeID": "53454447",
             "storeName": "Ye Olde Candy Shoppe",
             "city": "Cityville",
             "building": "1313",
             "street": "Vampire Lane",
             "zipcode": "99999",
             "storeSize": "large",
             "storeVisitDate": "5/3/12",
             "action": "Purchase",
             "dollarAmount": "12.43"
           },
           {
             "storeID": "53454447",
             "storeName": "Ye Olde Candy Shoppe",
             "city": "Cityville",
             "building": "1313",
             "street": "Vampire Lane",
             "zipcode": "99999",
             "storeSize": "large",
             "storeVisitDate": "5/3/12",
             "action": "Purchase",
             "dollarAmount": "5.43"
           }
         ]
       },
       {
         "key": "12/31/12",
         "values": [
           {
             "storeID": "53454447",
             "storeName": "Ye Olde Candy Shoppe",
             "city": "Cityville",
             "building": "1313",
             "street": "Vampire Lane",
             "zipcode": "99999",
             "storeSize": "large",
             "storeVisitDate": "12/31/12",
             "action": "Purchase",
             "dollarAmount": "2.53"
           }
         ]
       },
       {
         "key": "1/24/13",
         "values": [
           {
             "storeID": "53454447",
             "storeName": "Ye Olde Candy Shoppe",
             "city": "Cityville",
             "building": "1313",
             "street": "Vampire Lane",
             "zipcode": "99999",
             "storeSize": "large",
             "storeVisitDate": "1/24/13",
             "action": "Return",
             "dollarAmount": "2.53"
           },
           {
             "storeID": "53454447",
             "storeName": "Ye Olde Candy Shoppe",
             "city": "Cityville",
             "building": "1313",
             "street": "Vampire Lane",
             "zipcode": "99999",
             "storeSize": "large",
             "storeVisitDate": "1/24/13",
             "action": "Return",
             "dollarAmount": "64.22"
           }
         ]
       }
     ]
   },
   {
     "storeName": "Mike's Bikes",
     "address": "2626 Aardvark Circle, Townsville NY 88888",
     "zipCode": "88888",
     "storeSize": "small",
     "visits": [
       {
         "key": "8/8/14",
         "values": [
           {
             "storeID": "24335234",
             "storeName": "Mike's Bikes",
             "city": "Townsville",
             "building": "2626",
             "street": "Aardvark Circle",
             "zipcode": "88888",
             "storeSize": "small",
             "storeVisitDate": "8/8/14",
             "action": "Purchase",
             "dollarAmount": "443.55"
           },
           {
             "storeID": "24335234",
             "storeName": "Mike's Bikes",
             "city": "Townsville",
             "building": "2626",
             "street": "Aardvark Circle",
             "zipcode": "88888",
             "storeSize": "small",
             "storeVisitDate": "8/8/14",
             "action": "Purchase",
             "dollarAmount": "34"
           },
           {
             "storeID": "24335234",
             "storeName": "Mike's Bikes",
             "city": "Townsville",
             "building": "2626",
             "street": "Aardvark Circle",
             "zipcode": "88888",
             "storeSize": "small",
             "storeVisitDate": "8/8/14",
             "action": "Purchase",
             "dollarAmount": "12.32"
           }
         ]
       },
       {
         "key": "10/3/15",
         "values": [
           {
             "storeID": "24335234",
             "storeName": "Mike's Bikes",
             "city": "Townsville",
             "building": "2626",
             "street": "Aardvark Circle",
             "zipcode": "88888",
             "storeSize": "small",
             "storeVisitDate": "10/3/15",
             "action": "Purchase",
             "dollarAmount": "233.1"
           },
           {
             "storeID": "24335234",
             "storeName": "Mike's Bikes",
             "city": "Townsville",
             "building": "2626",
             "street": "Aardvark Circle",
             "zipcode": "88888",
             "storeSize": "small",
             "storeVisitDate": "10/3/15",
             "action": "Return",
             "dollarAmount": "44.99"
           }
         ]
       }
     ]
   }
 ]

沒錯! 您可以使用.map()完成大部分操作。 新的ES6標准使這一切變得更加容易,並且使用以下功能,您甚至都不會修改任何原始數據!:

array.map(store => {
  //return a new object that takes all the store info, then reassigns the visits key in a new object
  return Object.assign({}, store, {
    //map over visits, and reassign the key key to visitDate
    visits: store.visits.map(({ key: visitDate, values }) => {
      return {
        //return an obj with visit date
        visitDate,
        // do destructuring again to create objects of action,dollars
        transactions: values.map(({ action, dollarAmount: dollars }) => ({ action, dollars }))
      };
    })
  });
});

此處是jsFiddle上的工作示例 -只需打開JS控制台即可查看轉換后的數據集)

以下是有關解決方案的幾點說明:

  • 即使您的數據有更多的鍵(在您粘貼的樣本中)也可以使用(您提到這是一個簡化的集合,因此可能很重要)
  • 它使用“映射”很多,而不是手動遍歷數組。 我發現它更具可讀性。

     // Go over all stores stores.map(function(store) { // In each store, go over all visits. store.visits.map(function(visit) { // In each visit, copy 'key' to 'visitDate' // and 'values' to 'transactions'. // Then delete old names ('key' and 'values'). visit.visitDate = visit.key; visit.transactions = visit.values; delete visit.key; delete visit.values; // For each transaction, replace it with a simple // map with only 'action' and 'dollars'. visit.transactions = visit.transactions.map(function(tx) { return { action: tx.action, dollars: tx.dollarAmount }; }); }); }); 

請注意,在IE9和更高版本中支持map()

要重命名屬性,您可以創建一個具有相同值的新屬性,然后delete舊屬性。

您可以將其用於所有部分,但是在您的結構上,通過使用map()創建新的“優化”交易並將其分配給新的transactions屬性,將b,c,d組合在一起看起來更加巧妙。

 // (I put this in a function so the logic can be at the top of the snippet) function fixData(stores) { // loop stores and their visits for (var iStore = 0; iStore < stores.length; iStore++) { var store = stores[iStore]; for (var iVisit = 0; iVisit < store.visits.length; iVisit++) { var visit = store.visits[iVisit]; // (a) rename property key to visitDate // add a new property with the same value then delete the old property visit.visitDate = visit.key; delete visit.key; // (b) rename property values to transactions // add a new property with the same value then delete the old property // (c) delete the 8 redundant properties (from storeID to storeVisitDate) // we could delete keys but quicker to map a new object // (d) rename property dollarAmount to dollars. // just give the new object property a different name visit.transactions = visit.values.map(function(trans) { return { action: trans.action, dollars: trans.dollarAmount } }); delete visit.values; } } console.log(stores); } var stores = [{ "storeName": "Ye Olde Candy Shoppe", "address": "1313 Vampire Lane, Cityville NY 99999", "zipCode": "99999", "storeSize": "large", "visits": [{ "key": "5/3/12", "values": [{ "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "5/3/12", "action": "Return", "dollarAmount": "65.43" }, { "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "5/3/12", "action": "Purchase", "dollarAmount": "12.43" }, { "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "5/3/12", "action": "Purchase", "dollarAmount": "5.43" }] }, { "key": "12/31/12", "values": [{ "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "12/31/12", "action": "Purchase", "dollarAmount": "2.53" }] }, { "key": "1/24/13", "values": [{ "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "1/24/13", "action": "Return", "dollarAmount": "2.53" }, { "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "1/24/13", "action": "Return", "dollarAmount": "64.22" }] }] }, { "storeName": "Mike's Bikes", "address": "2626 Aardvark Circle, Townsville NY 88888", "zipCode": "88888", "storeSize": "small", "visits": [{ "key": "8/8/14", "values": [{ "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "8/8/14", "action": "Purchase", "dollarAmount": "443.55" }, { "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "8/8/14", "action": "Purchase", "dollarAmount": "34" }, { "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "8/8/14", "action": "Purchase", "dollarAmount": "12.32" }] }, { "key": "10/3/15", "values": [{ "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "10/3/15", "action": "Purchase", "dollarAmount": "233.1" }, { "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "10/3/15", "action": "Return", "dollarAmount": "44.99" }] }] }]; fixData(stores); 

如果我們假設您的數組稱為arr,我建議:

arr.forEach(function(currentValue, index, array) {
   currentValue.visits = currentValue.visits.map(function(currentValue, index, array) {
      currentValue.visitDate = currentValue.key;
      delete currentValue.key;
      currentValue.transactions = currentValue.values.map(function(currentValue, index, array) {
         currentValue = {action: currentValue.action, dollars: currentValue.dollarAmount};
         return currentValue;
      });
      delete currentValue.values;
      return currentValue;
   });
});

好吧,由於這是“數據”,而不是某些內存中的對象,所以我猜您是通過使用JSON.parse從JSON獲得的。 (如果沒有,您仍然可以通過首先使用JSON.strigify來使用此方法)

您知道JSON.parse接受用於控制此類事件的函數嗎? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

所以....

fixed=JSON.parse(dataString, function(key,value){
 if(key=="key"){this.visitDate=value;return}
 if(key=="values"){this.transactions=value;return}
 if(key=="somethingYouDontWant"){return;}
 //etc...
 return value;    
})

它純凈的javascript,沒有任何庫,並使用簡單的地圖:

 var y = x.map(function(xs){
      xs.visits = xs.visits.map(function (item){
        return {
          visitDate: item.key,
          transactions: item.values.map(function(v){
            return {
              action: v.action,
              dollars: v.dollarAmount
            };
          })
        };
      });
      return xs;
    });

Array.map()delete運算符的靈活解決方案:

var delete_props = ["storeID","storeName","city","building","street", "zipcode","storeSize", "storeVisitDate"];

 // arr is your initial array
 arr.map(function(obj){
     obj['visits'].map(function(inner_obj){
         inner_obj['visitDate'] = inner_obj['key'];
         delete inner_obj['key'];

         inner_obj['values'].map(function(values_obj){
            values_obj['dollars'] = values_obj['dollarAmount'];
            delete values_obj['dollarAmount'];

            delete_props.forEach(function(v){
                delete values_obj[v];
            });
        });
        inner_obj['transactions '] = inner_obj['values'];
        delete inner_obj['values'];

     });     
 });

這是另一種解決方案,代碼非常簡單,但尚未優化。

var obj = {}, key;
data.forEach(item => {
  item.visits.forEach(visit => {
    visit.visitDate = visit.key; 
    delete visit.key;
    visit.transactions = [];
    visit.values.forEach(value => {
      obj = {};
      for (key in value) {
        if (value.hasOwnProperty(key) && retain.indexOf(key) > -1) {
          obj[key] = value[key];
        }
      }
      visit.transactions.push(obj);
    });
    delete visit.values;
  });
console.log(item);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM