Estoy tratando de filtrar una matriz para obtener solo lo que quiero y lo he intentado con filter and reduce, pero no pude hacer que funcione por completo. Estoy tratando de obtener solo los objetos que tienen "System.State" con un "oldValue" y un "newValue"

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

El problema es que la matriz value contiene varios objetos que NO pueden tener "System.State" y algunos que tienen "System.State" pero solo con "newValue", en lugar de "oldValue" y {{ X5}}, por lo que recibo muchos errores indefinidos y realmente no sé cómo tratar estas situaciones.

Este es un ejemplo que no tiene "System.State" y otro que tiene "System.State "pero solo con "newValue":

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"
        }
      }
    },
  ]
}

Estoy usando TFS API si alguien quiere saber. Esto es lo que he intentado usar filter:

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

Y esto estaba usando reductor:

  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);

¿Qué estoy haciendo mal? Por cierto, estoy usando ['System.State'] porque no puedo acceder a una propiedad de objeto que tiene un punto.

1
ncesar 29 may. 2020 a las 23:03

3 respuestas

La mejor respuesta

En su filter ejemplo, reemplace data.value.fields.filter() con data.value.filter(), porque data.value es una matriz.

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;
  })

);
2
Typing 29 may. 2020 a las 20:12

Este data.value.fields no está definido, debe acceder a la propiedad fields a través de cada objeto dentro de la propiedad 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";
}));
1
Ele 29 may. 2020 a las 20:14

Simplemente filtre la propiedad value para incluir solo los elementos de la matriz que contienen:

"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>
0
terrymorse 29 may. 2020 a las 20:19