如何正确过滤具有对象数组的对象

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

我正在尝试过滤数组以仅获取我想要的内容,并且我尝试使用过滤和减少,但我无法使其完全正常工作。我试图只获取具有 "System.State""oldValue""newValue"

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

问题是 value 数组包含几个可能没有 "System.State" 的对象,有些对象有 "System.State" 但只有 "newValue",而不是 [=15] =] 和 "newValue",所以我收到了很多未定义的错误,我真的不知道如何处理这些情况。

这是一个没有 "System.State" 的例子,另一个例子有 "System.State" 但只有 "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"
        }
      }
    },
  ]
}

如果有人想知道的话,我正在使用 TFS API。这是我尝试使用过滤器的方法:

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

这是使用减速器:

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

我做错了什么?顺便说一句,我正在使用 ['System.State'] 因为我无法访问带有点的对象 属性。

在您的 filter 示例中,将 data.value.fields.filter() 替换为 data.value.filter(),因为 data.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": { // 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;
  })

);

data.value.fields未定义,您应该通过属性value中的每个对象访问属性fields

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

只需过滤 value 属性 以仅包含包含以下内容的数组元素:

"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>