【问题标题】:How do I filter through an array of object and retain the object key name?如何过滤对象数组并保留对象键名?
【发布时间】:2020-01-23 17:54:39
【问题描述】:

我有一些 JSON 数据,我试图过滤掉没有特定属性的 JSON 对象。

我可以使用filter function from Underscore.JS 成功过滤掉不具有正确属性的对象。

但是,当过滤器函数运行时,它会剥离对象的键名。

下面是过滤函数中变量data中使用的JSON:

{
    "Presentations": {
        "Instant": false,
        "Daily": false,
        "WeeklySummary": false,
        "ContentTypeId": 5
    },
    "Articles": {
        "Instant": true,
        "Daily": false,
        "WeeklySummary": true,
        "ContentTypeId": 1
    },
    "Blogs": {
        "Instant": true,
        "Daily": false,
        "WeeklySummary": true,
        "ContentTypeId": 61
    },
    "NewsBriefs": {
        "Instant": false,
        "Daily": false,
        "WeeklySummary": false,
        "ContentTypeId": 2
    },
    "SpecialInsights": {
        "Instant": false,
        "Daily": false,
        "WeeklySummary": false,
        "ContentTypeId": 50
    },
    "UserSelected": {
        "Frequency": null,
        "Value": false,
        "ContentTypeId": 0
    }
}

这是一个 JavaScript 过滤器函数,它返回一个必须包含 'Instant' 属性的对象数组

newArr = _.filter(data, function(obj){
              return obj.hasOwnProperty('Instant')
          });

如果我控制台记录 newArr,这就是我得到的:

[
   {
      "Instant":false,
      "Daily":false,
      "WeeklySummary":false,
      "ContentTypeId":5
   },
   {
      "Instant":true,
      "Daily":false,
      "WeeklySummary":true,
      "ContentTypeId":1
   },
   {
      "Instant":true,
      "Daily":false,
      "WeeklySummary":true,
      "ContentTypeId":61
   },
   {
      "Instant":false,
      "Daily":false,
      "WeeklySummary":false,
      "ContentTypeId":2
   },
   {
      "Instant":false,
      "Daily":false,
      "WeeklySummary":false,
      "ContentTypeId":50
   }
]

如您所见,它正确地过滤掉了不具有Instant 属性的对象,在本例中为UserSelected 对象。

但是,在该过程中,我丢失了对象键名称,例如 PresentationsArticles

过滤 JSON 数据时如何保留这些键名?

【问题讨论】:

  • 请同时添加想要的结果。
  • 您好,如果您愿意,我可以添加。输出将与 newArr 相同,但我们保留了原始 JSON 中的那些键名。我只是不想添加重复的代码和混淆问题。

标签: javascript json underscore.js


【解决方案1】:

你可以在没有任何库的情况下做到这一点:

Object.entries(data).filter(([key, value]) => {
  return value.hasOwnProperty('Instant')
}).reduce((acc, [key, value]) => {
  return { ...acc, [key]: value }
}, {})

您做错的是,您只在遍历字典时保留了值,但从未传递键。我猜你也可以使用新的fromEntries,但它的工作方式相同

【讨论】:

  • 您不需要.filter() 呼叫:Object.keys(data).reduce((result, current) => { if (current.hasOwnProperty("Instant")) { result[current] = Object.assign({}, input[current]); } return result; }, {})
  • @grokked 您好,所以当我运行您的代码时,第一个对象似乎存在问题,其中“演示文稿”的键被放入键名为“0”的对象中,其值为放入另一个键名为“1”的对象中。其余对象看起来正确,并且确实过滤了 UserSelected 对象。知道为什么第一个对象“Presentations”会这样拆分吗?
  • 我在代码中犯了一个错误,忘记在reduce函数中添加空对象作为第二个参数
  • @Andreas 你是对的,但你的代码不起作用,你应该使用data[current].hasOwnProperty("Instant")Object.entries
  • @grokked 你说得对。看起来我混合了两种解决方案......正确的版本:Object.keys(data).reduce((result, current) => { if (data[current].hasOwnProperty("Instant")) { result[current] = Object.assign({}, data[current]); } return result; }, {})
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 2022-07-20
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
相关资源
最近更新 更多