【问题标题】:what is the best way to remove certain objects from a nested object?从嵌套对象中删除某些对象的最佳方法是什么?
【发布时间】:2020-08-10 23:45:40
【问题描述】:

我有以下嵌套对象:


{
  "cards": {
    "1": {
      "x": 247,
      "y": 213,
      "properties": {
        "id": 1,
        "name": "a",
        "intros": {
          "intro_0": {
            "id": 1,
            "cardId": 1
          },
          "intro_1": {
            "id": 2,
            "cardId": 1
          },
          "intro_3": {
            "id": 24,
            "cardId": 1
          }
        },
        "exits": {
          "exit_0": {
            "id": 1,
            "cardId": 1
          },
          "exit_1": {
            "id": 22,
            "cardId": 1            
          }
        },
        "mixins": {
          "mixin_0": {
            "id": 23,
            "cardId": 1
          }
        }
      }
    },
    "3": {
      "x": 762,
      "y": 187,
      "properties": {
        "id": 1,
        "name": "x",
        "intros": {
          "intro_0": {
            "id": 1,
            "cardId": 1
          },
          "intro_1": {
            "id": 263,
            "cardId": 1
          }
        },
        "exits": {
          "exit_0": {
            "id": 1,
            "cardId": 1
          },
          "exit_1": {
            "id": 2,
            "cardId": 1
          }
        },
        "mixins": {
          "mixin_0": {
            "id": 3,
            "cardId": 1
          }
        },
      }
    },
    "4": {
      "x": 1200,
      "y": 187,
      "properties": {
        "id": 1,
        "name": "j",
        "intros": {
          "intro_0": {
            "id": 1,
            "cardId": 1
          },
          "intro_1": {
            "id": 276,
            "cardId": 1
          }
        },
        "exits": {
          "exit_0": {
            "id": 1,
            "cardId": 1
          },
          "exit_1": {
            "id": 2,
            "cardId": 1
          }
        },
        "mixins": {
          "mixin_0": {
            "id": 3,
            "cardId": 1
          }
        }
      }
    }
  }
}

我试图通过对象仅提取“intro”中的第一个和“exit”中的第一个,并修改原始对象,使其仅包含这些以及其余数据。或者相同的是,我想删除除第一个之外的所有“介绍”和除第一个之外的所有“退出”。 为了提取我想要的值,我做了 3 for in ... 但是在修改原始对象时,我认为我把它弄得太复杂了,必须有一些更简单的方法。

const cards: any = Object.values(data.cards);

      for (const indexCard in cards) {
        if (cards.hasOwnProperty(indexCard)) {
          const card = cards[indexCard];
          const cardIntros = card.properties.intros;
          for (const introIndex in cardIntros) {
            if (cardIntros.hasOwnProperty(introIndex) && introIndex === 'intro_0') {
              const firstIntro = cardIntros[introIndex];
              const cardsExits = card.properties.exits;
              for (const exitIndex in cardsExits) {
                if (cardsExits.hasOwnProperty(exitIndex) && exitIndex === 'exit_0') {
                  const firstExit = cardsExits[exitIndex];
                }
              }

            }
          }
        }
      }

有没有人看到一种更简单的方法来删除我想要删除的“intro”和“exits”,以便生成一个只包含所需“intro”和“exits”的新对象?

提前谢谢你!

【问题讨论】:

  • 这实际上比看起来更难,因为您的 introsexits 是一个对象而不是有序数组。我们是否应该假设 intro 和 exit 条目将始终以 _index 结尾,例如exit_0。我也假设 0 是您命名这些条目的起始索引?如果你创建了这个结构,我建议以后使用对象数组。
  • @DaneBrouwer 所有“介绍”和“退出”都以从 0 开始的有序索引结束。这是我看到的唯一指南。数据给了我。我想这不会那么容易,因为我找不到任何方法来直接删除我想要的东西

标签: javascript arrays object nested-object


【解决方案1】:

您可以创建递归函数来检查当前值是否为对象,然后检查该对象的某些键是否等于参数提供的键。如果它确实包含该键,它将从该对象中删除其他键。这适用于任何级别的嵌套。

const data = {"cards":{"1":{"x":247,"y":213,"properties":{"id":1,"name":"a","intros":{"intro_0":{"id":1,"cardId":1},"intro_1":{"id":2,"cardId":1},"intro_3":{"id":24,"cardId":1}},"exits":{"exit_0":{"id":1,"cardId":1},"exit_1":{"id":22,"cardId":1}},"mixins":{"mixin_0":{"id":23,"cardId":1}}}},"3":{"x":762,"y":187,"properties":{"id":1,"name":"x","intros":{"intro_0":{"id":1,"cardId":1},"intro_1":{"id":263,"cardId":1}},"exits":{"exit_0":{"id":1,"cardId":1},"exit_1":{"id":2,"cardId":1}},"mixins":{"mixin_0":{"id":3,"cardId":1}}}},"4":{"x":1200,"y":187,"properties":{"id":1,"name":"j","intros":{"intro_0":{"id":1,"cardId":1},"intro_1":{"id":276,"cardId":1}},"exits":{"exit_0":{"id":1,"cardId":1},"exit_1":{"id":2,"cardId":1}},"mixins":{"mixin_0":{"id":3,"cardId":1}}}}}}

function first(data, props = []) {
  return Object.entries(data).reduce((r, [k, v]) => {
    if (typeof v == 'object' && v != null) {
      if (Array.isArray(v)) {
        r[k] = v.map(e => first(e, props))
      } else {
        const value = { ...v }
        const check = props.some(p => Object.keys(v).includes(p))

        if (check) {
          for (let i in value) {
            if (!props.includes(i)) {
              delete value[i]
            }
          }
        }

        r[k] = first(value, props)
      }

    } else r[k] = v
    return r;
  }, {})
}


const result = first(data, ['intro_0', 'exit_0'])
console.log(result)

【讨论】:

  • 如果您的数据中有一个数组,这将不起作用。然后您可以修改原始数据或使用一些 deepClone 方法,然后修改该克隆对象。
  • 您可以编辑您的答案以包含您的评论:)
  • @NenadVracar 我正在检查您的解决方案,但是“const check = props.some(p => Object.keys(v).includes(p))”我收到一条错误消息“无法转换未定义或 null 反对”
  • 我猜你正在尝试一些其他数据,你能发布吗?
  • 在某些时候v 为空或未定义,这就是您收到错误的原因。
猜你喜欢
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
相关资源
最近更新 更多