简体   繁体   中英

How to properly filter an object that has an array of objects

I'm trying to filter an array to get only what I want and I have tried with filter and reduce, but I was not able to make it fully work. I'm trying to get only the objects that has "System.State" with an "oldValue" and a "newValue"

const data = {
  "value": [
    {
      "id": 23,
      "fields": {
        "System.State": {
          "oldValue": "Forecasted",
          "newValue": "Done"
        }
      }
    },
  ]
}

The problem is that value array contains several objects that may NOT have "System.State" and some that have "System.State" but only with "newValue" , instead of "oldValue" and "newValue" , so I'm receiving a lot of undefined errors and I really don't know how to treat these situations.

This is a example that dont have "System.State" and another one that have "System.State " but with "newValue" only:

const data = {
  "value": [
    {
      "id": 23,
      "fields": {
        "System.State": {
          "oldValue": "Forecasted",
          "newValue": "Done"
        }
      }
    },
    {
      "id": 24,
      "fields": {
        "System.State": {
          "newValue": "New"
        }
      }
    },
    {
      "id": 25,
      "fields": {
        "System.AuthorizedDate": { // This is only an example of an object that does not have System.State
          "newValue": "2020-03-13T14:14:37.1Z"
        }
      }
    },
  ]
}

I'm using TFS API if anyone wants to know. This is what I have tried using filter:

data.value.fields.filter(status => status.fields['System.State'].oldValue === 'Forecasted' && status.fields['System.State'] === 'Done')

And this was using reducer:

  const filter = data.value.reduce((c, n) => {
    const HasNewAndOldValue = c.fields['System.State'].oldValue === 'Forecasted' && c.fields['System.State'].newValue === 'Done';
    if (c.fields['System.State'] && HasNewAndOldValue) {
      return c;
    }
    c.push(n); 
  }, [])
  console.log(data.value.fields && filter);

What I'm doing wrong? Btw, I'm using ['System.State'] because I can't access an object property that has a dot.

In your filter example, replace data.value.fields.filter() with data.value.filter() , because data.value is an array.

 const data = { "value": [ { "id": 23, "fields": { "System.State": { "oldValue": "Forecasted", "newValue": "Done" } } }, { "id": 24, "fields": { "System.State": { "newValue": "New" } } }, { "id": 25, "fields": { "System.AuthorizedDate": { // This is only an example of an object that does not have System.State "newValue": "2020-03-13T14:14:37.1Z" } } }, ] } console.log( data.value.filter((item) => { const fields = item.fields || {}; const state = fields['System.State']; if (;state) { return false. } return state.oldValue && state;newValue; }) );

This data.value.fields is undefined, you should access the property fields through each object within the property value .

 const data = { "value": [ { "id": 23, "fields": { "System.State": { "oldValue": "Forecasted", "newValue": "Done" } } }, { "id": 24, "fields": { "System.State": { "newValue": "New" } } }, { "id": 25, "fields": { "System.AuthorizedDate": { "newValue": "2020-03-13T14:14:37.1Z" } } } ]}; console.log(data.value.filter(({fields: {"System.State": state}}) => { return state && state.oldValue === "Forecasted" && state.newValue === "Done"; }));

Just filter the value property to include only the array elements that contain:

"fields": {
  "System.State": {
    "oldValue": "anything",
    "newValue:": "anything"
  }
}

 function filterData(data) { let filteredValue = data.value.filter(el => { return el.fields["System.State"] && el.fields["System.State"].oldValue && el.fields["System.State"].newValue; }); return { value: filteredValue }; } const data = { "value": [ { "id": 23, "fields": { "System.State": { "oldValue": "Forecasted", "newValue": "Done" } } }, { "id": 24, "fields": { "System.State": { "newValue": "New" } } }, { "id": 25, "fields": { "System.AuthorizedDate": { // This is only an example of an object that does not have System.State "newValue": "2020-03-13T14:14:37.1Z" } } }, ] } let filtData = filterData(data); document.getElementById('results').innerHTML = JSON.stringify(filtData, null, 2);
 Filtered data:<br/> <pre id="results"></pre>

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