从嵌套数组对象中查找对象

Posted

技术标签:

【中文标题】从嵌套数组对象中查找对象【英文标题】:Find object from nested array object 【发布时间】:2021-08-31 23:50:30 【问题描述】:

我有一个带有嵌套数组对象的 json 数组,我想通过键名获取特定对象。我已经尝试了很多,但我需要一些通用的解决方案。

let data = "role":"http://www.icai.org/xbrl/taxonomy/role/in-ca/DisclosureOfGeneralInformationAboutCompany","facts":"concept":"in-ca:DisclosureOfGeneralInformationAboutCompanyAbstract","$t":"","facts":["concept":"in-ca:DisclosureOfCompanyInformationAbstract","$t":"","facts":["concept":"in-ca:NameOfCompany","d2016":"LAKSHMI ENERGY AND FOODS LIMITED","concept":"in-ca:CorporateIdentityNumber","d2016":"L00000CH1990PLC010573","concept":"in-ca:PermanentAccountNumberOfEntity","d2016":"AAACL3147J","concept":"in-ca:AddressOfRegisteredOfficeOfCompany","d2016":"SCO 18  19  1ST FLOOR SECTOR 9 D, MADHYA MARH   CHANDIGARH","concept":"in-ca:TypeOfIndustry","d2016":"Commercial and Industrial","concept":"in-ca:RegistrationDate","concept":"in-ca:CategoryOrSubcategoryOfCompany","concept":"in-ca:WhetherCompanyIsListedCompany"],"concept":"in-ca:DisclosureOfDocumentInformationAbstract","$t":"","facts":["concept":"in-ca:DateOfBoardMeetingWhenFinalAccountsWereApproved","d2016":"2016-05-09","concept":"in-ca:PeriodCoveredByFinancialStatements","concept":"in-ca:DateOfStartOfReportingPeriod","d2015":"2014-04-01","d2016":"2015-04-01","concept":"in-ca:DateOfEndOfReportingPeriod","d2015":"2015-03-31","d2016":"2016-03-31","concept":"in-ca:NatureOfReportStandaloneConsolidated","d2016":"Standalone","concept":"in-ca:ContentOfReport","d2016":"Financial Statements","concept":"in-ca:DescriptionOfPresentationCurrency","d2016":"INR","concept":"in-ca:LevelOfRoundingUsedInFinancialStatements","d2016":"Millions","concept":"in-ca:TypeOfCashFlowStatement","d2016":"Indirect Method","concept":"in-ca:DisclosureWebLinkOfCompanyAtWhichAnnualReportIsPlaced"],"concept":"in-ca:DisclosureOfOtherGeneralInformationAbstract","$t":"","facts":["concept":"in-ca:DateFromWhichRegisterOfMembersRemainedClosed","concept":"in-ca:DateTillWhichRegisterOfMembersRemainedClosed","concept":"in-ca:NameOfRegistrarAndTransferAgent","concept":"in-ca:AddressAndContactDetailsOfRegistrarAndTransferAgent","concept":"in-ca:WhetherCompanyIsMaintainingBooksOfAccountAndOtherRelevantBooksAndPapersInElectronicForm","d2016":"true","concept":"in-ca:PostalAddressOfPlaceOfMaintenanceOfComputerServersStoringAccountingDataAbstract","facts":["concept":"in-ca:CompletePostalAddressOfPlaceOfMaintenanceOfComputerServersStoringAccountingData","d2016":"Lakshmi Energy and Foods Limited Chandigarh-Ludhiana National Highway, at Khamanon, Punjab,","concept":"in-ca:NameOfCityOfPlaceOfMaintenanceOfComputerServersStoringAccountingData","d2016":"Chandigarh-Ludhiana National Highway, at Khamanon, Punjab,","concept":"in-ca:NameOfStateUnionTerritoryOfPlaceOfMaintenanceOfComputerServersStoringAccountingData","d2016":"Punjab","concept":"in-ca:PinCodeOfPlaceOfMaintenanceOfComputerServersStoringAccountingData","d2016":"141801","concept":"in-ca:NameOfDistrictOfPlaceOfMaintenanceOfComputerServersStoringAccountingData","d2016":"Punjab","concept":"in-ca:ISOCountryCodeOfPlaceOfMaintenanceOfComputerServersStoringAccountingData","d2016":"IN","concept":"in-ca:NameOfCountryOfPlaceOfMaintenanceOfComputerServersStoringAccountingData","d2016":"India","concept":"in-ca:PhoneWithSTDISDCodeOfPlaceOfMaintenanceOfComputerServersStoringAccountingData","d2016":"01628-661800"],"concept":"in-ca:ParticularsOfServiceProviderAbstract","$t":"","facts":["concept":"in-ca:NameOfTheServiceProvider","concept":"in-ca:InternetProtocolAddressOfServiceProvider","concept":"in-ca:LocationOfTheServiceProvider","concept":"in-ca:WhetherBooksOfAccountAndOtherBooksAndPapersAreMaintainedOnCloud","concept":"in-ca:AddressAsProvidedByTheServiceProvider"]],"concept":"in-ca:DisclosureOfPrincipalProductOrServicesAbstract","$t":"","facts":["concept":"in-ca:TotalNumberOfProductOrServiceCategory","concept":"in-ca:DescriptionOfPrincipalProductOrServicesCategory","concept":"in-ca:DisclosureOfPrincipalProductOrServicesTable","concept":"in-ca:DisclosureOfPrincipalProductOrServicesLineItems","$t":"","facts":["concept":"in-ca:ProductOrServiceCategoryITC4DigitCode","d2016_TypesOfPrincipalProductOrServicesAxis_Prod1":"1006","concept":"in-ca:DescriptionOfProductOrServiceCategory","d2016_TypesOfPrincipalProductOrServicesAxis_Prod1":"Rice and Paddy","concept":"in-ca:TurnoverOfProductOrServiceCategory","d2016_TypesOfPrincipalProductOrServicesAxis_Prod1":"8,784,320,000.00","concept":"in-ca:HighestTurnoverContributingProductOrServiceITC8DigitCode","d2016_TypesOfPrincipalProductOrServicesAxis_Prod1":"10061090","concept":"in-ca:DescriptionOfProductOrService","d2016_TypesOfPrincipalProductOrServicesAxis_Prod1":"Rice and Paddy","concept":"in-ca:UnitOfMeasurementOfHighestContributingProductOrService","d2016_TypesOfPrincipalProductOrServicesAxis_Prod1":"kg","concept":"in-ca:TurnoverOfHighestContributingProductOrService","d2016_TypesOfPrincipalProductOrServicesAxis_Prod1":"8,784,320,000.00","concept":"in-ca:QuantityOfHighestContributingProductOrServiceInUom"]]]

实际上,这个对象有一个事实键,而如果概念键与传递的键匹配,我需要获取数据,因此它应该返回特定对象。如果您有任何通用解决方案,请分享。我已经创建了一个解决方案,但这是一个肮脏的解决方案,并且可能会在某个时间点中断。

const getObj = (data, key, subKey) =>
let obj = ;
key = `:$key`;
data.forEach((v)=>
    if(v.facts)
        if(v.facts.length > 0)
            v.facts.forEach((m)=>
                if(m.facts)
                    if(m.facts.length > 0)
                        m.facts.forEach((n)=>
                            if(n.facts)
                                if(n.facts.length > 0)
                                    n.facts.forEach((o)=>
                                        if(o.concept.includes(key)) 
                                            obj = o;
                                            return true;
                                        
                                    )
                                
                                else
                                    if(n.concept.includes(key)) 
                                        obj = n;
                                        return true;
                                    
                                
                            
                            else 
                                if(n.concept.includes(key)) 
                                    obj = n;
                                    return true;
                                
                            
                        )
                    
                    else
                        if(m.concept.includes(key)) 
                            obj = m;
                            return true;
                        
                    
                
                else
                    if(m.concept.includes(key)) 
                        obj = m;
                        return true;
                    
                
            )
        
        else
            if(v.concept.includes(key)) 
                obj = v;
                return true;
            
        
    
    else
        if(v.concept == key) 
            obj = v;
            return true;
        
    
);

let value = "";
if(obj[`i$subKey`]) value = obj[`i$subKey`];
else if(obj[`d$subKey`]) value = obj[`d$subKey`];
else if(obj[subKey]) value = obj[subKey];

return value;

请帮我解决这个问题

【问题讨论】:

facts 总是一个数组吗?请添加您的要求及其结果。 我从来没有这么多的forEach 循环嵌套在内部和内部并且深入。您的代码首先需要进行大量清理。这段代码现在应该很慢,因为占用了太多内存。 @NinaScholz 不,如果里面没有嵌套数组,它可能是对象,如果事实是嵌套的,那么我们需要深入搜索 return true 不会终止 forEach。它将处理数组中的每一项。 另外,请添加输入和预期输出。您可以通过遍历嵌套对象的简单递归来解决这个问题。 【参考方案1】:

您可以采用短路的递归方法。

const
    find = (object, key, value) => 
        if (!object) return;
        if ((object[key] || '').includes(value)) return object;
        let target;
        [].concat(object.facts).some(o => target = find(o, key, value));
        return target;
    ,
    data =  role: "http://www.icai.org/xbrl/taxonomy/role/in-ca/DisclosureOfGeneralInformationAboutCompany", facts:  concept: "in-ca:DisclosureOfGeneralInformationAboutCompanyAbstract", $t: "", facts: [ concept: "in-ca:DisclosureOfCompanyInformationAbstract", $t: "", facts: [ concept: "in-ca:NameOfCompany", d2016: "LAKSHMI ENERGY AND FOODS LIMITED" ,  concept: "in-ca:CorporateIdentityNumber", d2016: "L00000CH1990PLC010573" ,  concept: "in-ca:PermanentAccountNumberOfEntity", d2016: "AAACL3147J" ,  concept: "in-ca:AddressOfRegisteredOfficeOfCompany", d2016: "SCO 18  19  1ST FLOOR SECTOR 9 D, MADHYA MARH   CHANDIGARH" ,  concept: "in-ca:TypeOfIndustry", d2016: "Commercial and Industrial" ,  concept: "in-ca:RegistrationDate" ,  concept: "in-ca:CategoryOrSubcategoryOfCompany" ,  concept: "in-ca:WhetherCompanyIsListedCompany" ] ,  concept: "in-ca:DisclosureOfDocumentInformationAbstract", $t: "", facts: [ concept: "in-ca:DateOfBoardMeetingWhenFinalAccountsWereApproved", d2016: "2016-05-09" ,  concept: "in-ca:PeriodCoveredByFinancialStatements" ,  concept: "in-ca:DateOfStartOfReportingPeriod", d2015: "2014-04-01", d2016: "2015-04-01" ,  concept: "in-ca:DateOfEndOfReportingPeriod", d2015: "2015-03-31", d2016: "2016-03-31" ,  concept: "in-ca:NatureOfReportStandaloneConsolidated", d2016: "Standalone" ,  concept: "in-ca:ContentOfReport", d2016: "Financial Statements" ,  concept: "in-ca:DescriptionOfPresentationCurrency", d2016: "INR" ,  concept: "in-ca:LevelOfRoundingUsedInFinancialStatements", d2016: "Millions" ,  concept: "in-ca:TypeOfCashFlowStatement", d2016: "Indirect Method" ,  concept: "in-ca:DisclosureWebLinkOfCompanyAtWhichAnnualReportIsPlaced" ] ,  concept: "in-ca:DisclosureOfOtherGeneralInformationAbstract", $t: "", facts: [ concept: "in-ca:DateFromWhichRegisterOfMembersRemainedClosed" ,  concept: "in-ca:DateTillWhichRegisterOfMembersRemainedClosed" ,  concept: "in-ca:NameOfRegistrarAndTransferAgent" ,  concept: "in-ca:AddressAndContactDetailsOfRegistrarAndTransferAgent" ,  concept: "in-ca:WhetherCompanyIsMaintainingBooksOfAccountAndOtherRelevantBooksAndPapersInElectronicForm", d2016: "true" ,  concept: "in-ca:PostalAddressOfPlaceOfMaintenanceOfComputerServersStoringAccountingDataAbstract", facts: [ concept: "in-ca:CompletePostalAddressOfPlaceOfMaintenanceOfComputerServersStoringAccountingData", d2016: "Lakshmi Energy and Foods Limited Chandigarh-Ludhiana National Highway, at Khamanon, Punjab," ,  concept: "in-ca:NameOfCityOfPlaceOfMaintenanceOfComputerServersStoringAccountingData", d2016: "Chandigarh-Ludhiana National Highway, at Khamanon, Punjab," ,  concept: "in-ca:NameOfStateUnionTerritoryOfPlaceOfMaintenanceOfComputerServersStoringAccountingData", d2016: "Punjab" ,  concept: "in-ca:PinCodeOfPlaceOfMaintenanceOfComputerServersStoringAccountingData", d2016: "141801" ,  concept: "in-ca:NameOfDistrictOfPlaceOfMaintenanceOfComputerServersStoringAccountingData", d2016: "Punjab" ,  concept: "in-ca:ISOCountryCodeOfPlaceOfMaintenanceOfComputerServersStoringAccountingData", d2016: "IN" ,  concept: "in-ca:NameOfCountryOfPlaceOfMaintenanceOfComputerServersStoringAccountingData", d2016: "India" ,  concept: "in-ca:PhoneWithSTDISDCodeOfPlaceOfMaintenanceOfComputerServersStoringAccountingData", d2016: "01628-661800" ] ,  concept: "in-ca:ParticularsOfServiceProviderAbstract", $t: "", facts: [ concept: "in-ca:NameOfTheServiceProvider" ,  concept: "in-ca:InternetProtocolAddressOfServiceProvider" ,  concept: "in-ca:LocationOfTheServiceProvider" ,  concept: "in-ca:WhetherBooksOfAccountAndOtherBooksAndPapersAreMaintainedOnCloud" ,  concept: "in-ca:AddressAsProvidedByTheServiceProvider" ] ] ,  concept: "in-ca:DisclosureOfPrincipalProductOrServicesAbstract", $t: "", facts: [ concept: "in-ca:TotalNumberOfProductOrServiceCategory" ,  concept: "in-ca:DescriptionOfPrincipalProductOrServicesCategory" ,  concept: "in-ca:DisclosureOfPrincipalProductOrServicesTable" ,  concept: "in-ca:DisclosureOfPrincipalProductOrServicesLineItems", $t: "", facts: [ concept: "in-ca:ProductOrServiceCategoryITC4DigitCode", d2016_TypesOfPrincipalProductOrServicesAxis_Prod1: "1006" ,  concept: "in-ca:DescriptionOfProductOrServiceCategory", d2016_TypesOfPrincipalProductOrServicesAxis_Prod1: "Rice and Paddy" ,  concept: "in-ca:TurnoverOfProductOrServiceCategory", d2016_TypesOfPrincipalProductOrServicesAxis_Prod1: "8,784,320,000.00" ,  concept: "in-ca:HighestTurnoverContributingProductOrServiceITC8DigitCode", d2016_TypesOfPrincipalProductOrServicesAxis_Prod1: "10061090" ,  concept: "in-ca:DescriptionOfProductOrService", d2016_TypesOfPrincipalProductOrServicesAxis_Prod1: "Rice and Paddy" ,  concept: "in-ca:UnitOfMeasurementOfHighestContributingProductOrService", d2016_TypesOfPrincipalProductOrServicesAxis_Prod1: "kg" ,  concept: "in-ca:TurnoverOfHighestContributingProductOrService", d2016_TypesOfPrincipalProductOrServicesAxis_Prod1: "8,784,320,000.00" ,  concept: "in-ca:QuantityOfHighestContributingProductOrServiceInUom" ] ] ]  ;

console.log(find(data, 'concept', 'foo'));
console.log(find(data, 'concept', 'in-ca:DisclosureOfOtherGeneralInformationAbstract'));
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

以上是关于从嵌套数组对象中查找对象的主要内容,如果未能解决你的问题,请参考以下文章

通过在嵌套的对象数组中查找多个条件来过滤数组

JavaScript 如何查找嵌套中的element对象

javascript在嵌套对象/数组中按值查找

在 ES6 深度嵌套的对象的 javascript 数组中查找值

mongodb $查找带有投影的数组中的嵌套对象

mongoDB对嵌套对象数组的聚合查找