簡體   English   中英

JSON 對象中的遞歸數據

[英]Recursive data in JSON object

{
"groups": [
    {
        "name": "Event",
        "groups": [
            {
                "name": "Service",
                "subscriptions": [
                    {
                        "topic": "SERVICE_STATUS_PRESETS"
                    },
                    {
                        "topic": "AIRCRAFT_ACTIVATION",

                    },
                    {
                        "topic": "OUT_OF_SERVICE",

                    }
                ]
            }
        ]
    },
    {
        "name": "Enquiries",
        "groups": [
            {
                "name": "Service-related",
                "subscriptions": [
                    {

                        "topic": "PROMO_CODES_REQUESTS",

                    }
                ]
            }
        ]
    }
],
"subscriptions": [
    {
        "topic": "BANNERS",
    },
    {
        "topic": "DOCUMENTS",
    },
    {
        "topic": "USER",
    }
]

}

好的,我有這樣的 JSON 結構,我需要的是:返回數組中的所有主題,在本例中它將是:

[“SERVICE_STATUS_PRESETS”、“AIRCRAFT_ACTIVATION”、“OUT_OF_SERVICE”、“PROMO_CODES_REQUESTS”、“BANNERS”、“DOCUMENTS”、“USER”]

我嘗試這樣的遞歸調用,雖然我只得到最后三個記錄:

getRecursive() {
if (Array.isArray(data)) {
       for (let i = 0; i < data.length; i++) {
         if (data[i].subscriptions) {
           return data[i].subscriptions.map((val: SubscriptionGroupDetails) => val.topic);
         } else if (data[i].groups) {
           return this.getAllTopics(data[i].groups);
         }
       }
     }
     if (data && data.groups) {
      return this.getAllTopics(data.groups);
     }
     return data.subscriptions.map((val: SubscriptionGroupDetails) => val.topic);
}

您可以采用遞歸方法並檢查

  • 如果移交的數據不是檢查對象,則返回空數組,
  • 如果對象具有想要的屬性,則返回一個值為topic的數組,
  • 或者獲取值並使用該函數進行遞歸調用並返回一個帶有結果的數組。

 function getTopics(object) { if (!object || typeof object !== 'object') return []; if ('topic' in object) return [object.topic]; return Object.values(object).reduce((r, v) => [...r, ...getTopics(v)], []); } var data = { groups: [{ name: "Event", groups: [{ name: "Service", subscriptions: [{ topic: "SERVICE_STATUS_PRESETS" }, { topic: "AIRCRAFT_ACTIVATION" }, { topic: "OUT_OF_SERVICE" }] }] }, { name: "Enquiries", groups: [{ name: "Service-related", subscriptions: [{ topic: "PROMO_CODES_REQUESTS" }] }] }], subscriptions: [{ topic: "BANNERS" }, { topic: "DOCUMENTS" }, { topic: "USER" }] }, result = getTopics(data); console.log(result);

這是使用對象掃描的解決方案

 // const objectScan = require('object-scan'); const data = {"groups":[{"name":"Event","groups":[{"name":"Service","subscriptions":[{"topic":"SERVICE_STATUS_PRESETS"},{"topic":"AIRCRAFT_ACTIVATION"},{"topic":"OUT_OF_SERVICE"}]}]},{"name":"Enquiries","groups":[{"name":"Service-related","subscriptions":[{"topic":"PROMO_CODES_REQUESTS"}]}]}],"subscriptions":[{"topic":"BANNERS"},{"topic":"DOCUMENTS"},{"topic":"USER"}]}; const searchTopics = (obj) => objectScan(['**.topic'], { rtn: 'value' })(obj); console.log(searchTopics(data)); /* => [ 'USER', 'DOCUMENTS', 'BANNERS', 'PROMO_CODES_REQUESTS', 'OUT_OF_SERVICE', 'AIRCRAFT_ACTIVATION', 'SERVICE_STATUS_PRESETS' ] */
 .as-console-wrapper {max-height: 100% !important; top: 0}
 <script src="https://bundle.run/object-scan@13.7.1"></script>

免責聲明:我是對象掃描的作者

如果您有興趣,此版本采用函數式方法。 上面還有其他的,但這只是另一種看待它的方式。

const recursion = object => Object.entries(object).map(([a, b]) => {
  if (a === 'topic') return b;
  if (Array.isArray(b)) return b.map(recursion);
  return [];
}).flat(Infinity);

recursion(obj);

編輯:添加了另一種使用.reduce() 的方法

您可以創建一個空的topics數組,然后遞歸地瀏覽嵌套結構,每次遇到它時添加一個主題,使用 javascript .forEach()循環瀏覽任何嵌套groupssubscriptions

let topics = [];

let findTopics = obj => {
   if (obj.groups) {
      obj.groups.forEach(findTopics);
   }
   if (obj.subscriptions) {
      obj.subscriptions.forEach(findTopics);
   }
   if (obj.topic) {
      topics.push(obj.topic);
   }
}

findTopics(data);

或者使用.reduce()的可能更簡潔的方法:

let findTopicsRecursive = (topics, obj) => {
   if (obj.groups) {
      topics = obj.groups.reduce(findTopicsRecursive, topics);
   }
   if (obj.subscriptions) {
      topics = obj.subscriptions.reduce(findTopicsRecursive, topics);
   }
   if (obj.topic) {
      topics.push(obj.topic);
   }
   return topics;
}

let findTopics = data => findTopicsRecursive([], data);

let topics = findTopics(data);

用這個:

function getTopics(obj){
   if(typeof obj !== 'object') return [];
   if(obj.topic) return [obj.topic];
   var res = [];
   for(var i in obj){
     res.push(...getTopics(obj[i]));
   }
   return res;
}

工作示例:

 const topics = { "groups": [ { "name": "Event", "groups": [ { "name": "Service", "subscriptions": [ { "topic": "SERVICE_STATUS_PRESETS" }, { "topic": "AIRCRAFT_ACTIVATION", }, { "topic": "OUT_OF_SERVICE", } ] } ] }, { "name": "Enquiries", "groups": [ { "name": "Service-related", "subscriptions": [ { "topic": "PROMO_CODES_REQUESTS", } ] } ] } ], "subscriptions": [ { "topic": "BANNERS", }, { "topic": "DOCUMENTS", }, { "topic": "USER", } ] } function getTopics(obj){ if(typeof obj !== 'object') return []; if(obj.topic) return [obj.topic]; var res = []; for(var i in obj){ res.push(...getTopics(obj[i])); } return res; } console.log(getTopics(topics));

暫無
暫無

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

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