简体   繁体   中英

Filter an Array of Objects from another Array of Objects with a different nesting structure

I have 2 arrays. I need to change the key-value pair of the Objects in originalArray based on the objects from compareArray

    let originalArray = [
  {
    reportCatalogId: 111,
    catalogRootId: 11,
    reports: [
      {
        reportId: 90001,
        reportCatalogId: 111,
        provisioning: true
      },
      {
        reportId: 90002,
        reportCatalogId: 111,
        provisioning: true
      },
      {
        reportId: 90003,
        reportCatalogId: 111,
        provisioning: true
      }
    ]
  },
  {
    reportCatalogId: 112,
    catalogRootId: 11,
    reports: [
      {
        reportId: 90004,
        reportCatalogId: 112,
        provisioning: true
      },
      {
        reportId: 90005,
        reportCatalogId: 112,
        provisioning: true
      },
      {
        reportId: 90006,
        reportCatalogId: 112,
        provisioning: true
      },
      {
        reportId: 90007,
        reportCatalogId: 112,
        provisioning: true
      }
    ]
  }
];
let compareArray = [
  {
    "reportId": 90001,
    "reportCatalogId": 111,
    "provisioning": true
  },
  {
    "reportId": 90006,
    "reportCatalogId": 112,
    "provisioning": true
  },
  {
    "reportId": 90007,
    "reportCatalogId": 112,
    "provisioning": true
  },
  {
    "reportId": 90003,
    "reportCatalogId": 111,
    "provisioning": true
  }
]

I need to check if the object from compareArray is present in originalArray based on the reportId . If it is not present, then the respective object's key provisioning value should be changed into false .

Desired Output:

    let output = [
  {
    reportCatalogId: 111,
    catalogRootId: 11,
    reports: [
      {
        reportId: 90001,
        reportCatalogId: 111,
        provisioning: true
      },
      {
        reportId: 90002,
        reportCatalogId: 111,
        provisioning: false
      },
      {
        reportId: 90003,
        reportCatalogId: 111,
        provisioning: true
      }
    ]
  },
  {
    reportCatalogId: 112,
    catalogRootId: 11,
    reports: [
      {
        reportId: 90004,
        reportCatalogId: 112,
        provisioning: false
      },
      {
        reportId: 90005,
        reportCatalogId: 112,
        provisioning: false
      },
      {
        reportId: 90006,
        reportCatalogId: 112,
        provisioning: true
      },
      {
        reportId: 90007,
        reportCatalogId: 112,
        provisioning: true
      }
    ]
  }
];

What I tried so far is that

const newArray = originalArray.map((catalog) => catalog.reports.map((report) => {
  if (report.reportId !== compArray.map(id => id.reportId)) {
    return {...report, provisioning : false}
  } 
}))

But I could not produce the desired output with my above code. Glad if someone could show me a pointer.

Try this

originalArray.map(({reports, ...catalog}) => ({
    ...catalog,
    reports: reports.map((report) => ({
        ...report,
        provisioning: compareArray.some(({ reportId }) => reportId === report.reportId),
    })),
}));

Don't write the data by hand. Write functions to create your catalog and report data -

const catalog = (reportCatalogId, catalogRootId = null, reports = []) =>
  ({ reportCatalogId, catalogRootId, reports })

const report = (reportId, reportCatalogId = null, provisioning = false) =>
  ({ reportId, reportCatalogId, provisioning })

And make functions like updateProvisions to work on the data -

function updateProvisioning(cat, prov) {
  return catalog(cat.reportCatalogId, cat.catalogRootId, cat.reports.map(r =>
    report(r.reportId, r.reportCatalogId, prov.has(r.reportId))
  ))
}

Notice how the underlying cat is not modified. Instead a new data is returned.

Finally, construct a Set of the report IDs from the compareArray -

let compareArray =
  [{"reportId": 90001,"reportCatalogId": 111,"provisioning": true},{"reportId": 90006,"reportCatalogId": 112,"provisioning": true},{"reportId": 90007,"reportCatalogId": 112,"provisioning": true},{"reportId": 90003,"reportCatalogId": 111,"provisioning": true}]

let hasProvisioning =
  new Set(compareArray.map(x => x.reportId))

Now you simply map our new updateProvisioning function over each category -

let newArray =
  originalArray.map(cat => updateProvisioning(cat, hasProvisioning))

Run the demo below to verify the result in your own browser -

 const catalog = (reportCatalogId, catalogRootId = null, reports = []) => ({ reportCatalogId, catalogRootId, reports }) const report = (reportId, reportCatalogId = null, provisioning = false) => ({ reportId, reportCatalogId, provisioning }) let compareArray = [{"reportId": 90001,"reportCatalogId": 111,"provisioning": true},{"reportId": 90006,"reportCatalogId": 112,"provisioning": true},{"reportId": 90007,"reportCatalogId": 112,"provisioning": true},{"reportId": 90003,"reportCatalogId": 111,"provisioning": true}] let hasProvisioning = new Set(compareArray.map(x => x.reportId)) let originalArray = [{reportCatalogId: 111,catalogRootId: 11,reports: [{reportId: 90001,reportCatalogId: 111,provisioning: true},{reportId: 90002,reportCatalogId: 111,provisioning: true},{reportId: 90003,reportCatalogId: 111,provisioning: true}]},{reportCatalogId: 112,catalogRootId: 11,reports: [{reportId: 90004,reportCatalogId: 112,provisioning: true},{reportId: 90005,reportCatalogId: 112,provisioning: true},{reportId: 90006,reportCatalogId: 112,provisioning: true},{reportId: 90007,reportCatalogId: 112,provisioning: true}]}] function updateProvisioning(cat, hasProvisioning) { return catalog(cat.reportCatalogId, cat.catalogRootId, cat.reports.map(r => report(r.reportId, r.reportCatalogId, hasProvisioning.has(r.reportId)) )) } let newArray = originalArray.map(cat => updateProvisioning(cat, hasProvisioning)) console.log(newArray)
 .as-console-wrapper { min-height: 100%; top: 0; }

[
  {
    "reportCatalogId": 111,
    "catalogRootId": 11,
    "reports": [
      {
        "reportId": 90001,
        "reportCatalogId": 111,
        "provisioning": true
      },
      {
        "reportId": 90002,
        "reportCatalogId": 111,
        "provisioning": false     // <-
      },
      {
        "reportId": 90003,
        "reportCatalogId": 111,
        "provisioning": true
      }
    ]
  },
  {
    "reportCatalogId": 112,
    "catalogRootId": 11,
    "reports": [
      {
        "reportId": 90004,
        "reportCatalogId": 112,
        "provisioning": false     // <-
      },
      {
        "reportId": 90005,
        "reportCatalogId": 112,
        "provisioning": false     // <-
      },
      {
        "reportId": 90006,
        "reportCatalogId": 112,
        "provisioning": true
      },
      {
        "reportId": 90007,
        "reportCatalogId": 112,
        "provisioning": true
      }
    ]
  }
]

Lodash if you don't mind.

 const originalArray = [{"reportCatalogId":111,"catalogRootId":11,"reports":[{"reportId":90001,"reportCatalogId":111,"provisioning":true},{"reportId":90002,"reportCatalogId":111,"provisioning":true},{"reportId":90003,"reportCatalogId":111,"provisioning":true}]},{"reportCatalogId":112,"catalogRootId":11,"reports":[{"reportId":90004,"reportCatalogId":112,"provisioning":true},{"reportId":90005,"reportCatalogId":112,"provisioning":true},{"reportId":90006,"reportCatalogId":112,"provisioning":true},{"reportId":90007,"reportCatalogId":112,"provisioning":true}]}]; const compareArray = [{"reportId":90001,"reportCatalogId":111,"provisioning":true},{"reportId":90006,"reportCatalogId":112,"provisioning":true},{"reportId":90007,"reportCatalogId":112,"provisioning":true},{"reportId":90003,"reportCatalogId":111,"provisioning":true}]; const compareIds = compareArray.map(({ reportId }) => reportId); const hasCompareId = (id) => compareIds.includes(id); const result = _.cloneDeepWith(originalArray, (_, key, obj) => { if (key === 'provisioning') return hasCompareId(obj.reportId); }); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top: 0 }
 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>

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