简体   繁体   中英

How to reduce an array of objects inside an array of objects based on another array

Is array reduce the best option for this or any other better options like using lodash

For eg:- The array that needs to be reduced

let A1 = [
    {
    "id": 1,
    "agency": "Sel A.",
    "analysis": [
        {"quarter": "Q4"," comment": "Test Data 1"},
        {"quarter": "Q3", "comment": "Test Data 2"},
        {"quarter": "Q2", "comment": "Test Data 3"}]
    },
    {
    "id": 2,
    "agency": "Sel B.",
    "analysis": [
        {"quarter": "Q1", "comment": "Test Data 4"},
        {"quarter": "Q3", "comment": "Test Data 5"},
        {"quarter": "Q4", "comment": "Test Data 6"}]
    },
    {
    "id": 3,
    "agency": "Sel C.",
    "analysis": [
        {"quarter": "Q2", "comment": "Test Data 7"},
        {"quarter": "Q3", "comment": "Test Data 8"},
        {"quarter": "Q4", "comment": "Test Data 9"}]
    },
    {
    "id": 4,
    "agency": "Sel D.",
    "analysis": [
        {"quarter": "Q1", "comment": "Test Data 10"},
        {"quarter": "Q4", "comment": ""},
        {"quarter": "Q3", "comment": "Test Data 12"}]
    }
];

The array with which we get the filter

let A2 = ['Q3', Q4];

How to reduce array like below where it only filter 'Q3' and 'Q4' and also check if comment is not empty.

let res = [
    {
    "id": 1,
    "agency": "Sel A.",
    "analysis": [
        {"quarter": "Q4"," comment": "Test Data 1"},
        {"quarter": "Q3", "comment": "Test Data 2"}],
    },
    {
    "id": 2,
    "agency": "Sel B.",
    "analysis": [,
        {"quarter": "Q3", "comment": "Test Data 5"},
        {"quarter": "Q4", "comment": "Test Data 6"}]
    },
    {
    "id": 3,
    "agency": "Sel C.",
    "analysis": [
        {"quarter": "Q3", "comment": "Test Data 8"},
        {"quarter": "Q4", "comment": "Test Data 9"}]
    },
    {
    "id": 4,
    "agency": "Sel D.",
    "analysis": [
        {"quarter": "Q3", "comment": "Test Data 12"}]
    }
]

Below implementation is using lodash library

 let A1 = [{ "id": 1, "agency": "Sel A.", "analysis": [{ "quarter": "Q4", " comment": "Test Data 1" }, { "quarter": "Q3", "comment": "Test Data 2" }, { "quarter": "Q2", "comment": "Test Data 3" } ] }, { "id": 2, "agency": "Sel B.", "analysis": [{ "quarter": "Q1", "comment": "Test Data 4" }, { "quarter": "Q3", "comment": "Test Data 5" }, { "quarter": "Q4", "comment": "Test Data 6" } ] }, { "id": 3, "agency": "Sel C.", "analysis": [{ "quarter": "Q2", "comment": "Test Data 7" }, { "quarter": "Q3", "comment": "Test Data 8" }, { "quarter": "Q4", "comment": "Test Data 9" } ] }, { "id": 4, "agency": "Sel D.", "analysis": [{ "quarter": "Q1", "comment": "Test Data 10" }, { "quarter": "Q4", "comment": "" }, { "quarter": "Q3", "comment": "Test Data 12" } ] } ]; let A2 = ['Q3', 'Q4']; var result = _.map(A1, x => { x.analysis = _.filter(x.analysis, analysisChild => A2.includes(analysisChild.quarter)); return x; }); console.log(result);
 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js" integrity="sha256-qXBd/EfAdjOA2FGrGAG+b3YBn2tn5A6bhz+LSgYD96k=" crossorigin="anonymous"></script>

You don't need to use reduce nor lodash , you can just use forEach on A1 and then use filter on analysis

 let A1 = [{ "id": 1, "agency": "Sel A.", "analysis": [{ "quarter": "Q4", "comment": "Test Data 1" }, { "quarter": "Q3", "comment": "Test Data 2" }, { "quarter": "Q2", "comment": "Test Data 3" } ] }, { "id": 2, "agency": "Sel B.", "analysis": [{ "quarter": "Q1", "comment": "Test Data 4" }, { "quarter": "Q3", "comment": "Test Data 5" }, { "quarter": "Q4", "comment": "Test Data 6" } ] }, { "id": 3, "agency": "Sel C.", "analysis": [{ "quarter": "Q2", "comment": "Test Data 7" }, { "quarter": "Q3", "comment": "Test Data 8" }, { "quarter": "Q4", "comment": "Test Data 9" } ] }, { "id": 4, "agency": "Sel D.", "analysis": [{ "quarter": "Q1", "comment": "Test Data 10" }, { "quarter": "Q4", "comment": "" }, { "quarter": "Q3", "comment": "Test Data 12" } ] } ]; let A2 = ['Q3', 'Q4']; A1.forEach(item => item.analysis = item.analysis.filter(analysis => A2.includes(analysis.quarter) && analysis.comment )) console.log(A1)

The tricky part is that the filter happens on a inner level

 let A1 = [ { "id": 1, "agency": "Sel A.", "analysis": [ {"quarter": "Q4"," comment": "Test Data 1"}, {"quarter": "Q3", "comment": "Test Data 2"}, {"quarter": "Q2", "comment": "Test Data 3"}] }, { "id": 2, "agency": "Sel B.", "analysis": [ {"quarter": "Q1", "comment": "Test Data 4"}, {"quarter": "Q3", "comment": "Test Data 5"}, {"quarter": "Q4", "comment": "Test Data 6"}] }, { "id": 3, "agency": "Sel C.", "analysis": [ {"quarter": "Q2", "comment": "Test Data 7"}, {"quarter": "Q3", "comment": "Test Data 8"}, {"quarter": "Q4", "comment": "Test Data 9"}] }, { "id": 4, "agency": "Sel D.", "analysis": [ {"quarter": "Q1", "comment": "Test Data 10"}, {"quarter": "Q4", "comment": ""}, {"quarter": "Q3", "comment": "Test Data 12"}] } ]; let A2 = ['Q3','Q4']; const res = A1.map( x => { const {analysis,...rest} = x return { analysis: analysis.filter(q => A2.includes(q.quarter) && q.comment ), ...rest } }); console.log(res)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM