【问题标题】:How to get distinct value from an array of objects containing array如何从包含数组的对象数组中获取不同的值
【发布时间】:2022-01-22 01:34:32
【问题描述】:

我正在尝试从下面的数据结构中获取一组不同的值。我尝试使用 reduce 和 object 键,但没有成功。有人可以指出我正确的方向吗?

数据:

var data = [{
    "id": 1,
    "Technologies": ["SharePoint", "PowerApps"]
  },
  {
    "id": 2,
    "Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
  },
  {
    "id": 3,
    "Technologies": ["SharePoint"]
  },
  {
    "id": 4,
    "Technologies": ["PowerApps"]
  },
  {
    "id": 5,
    "Technologies": null
  }
]

完成的结果应如下所示:

var distintValues = ["PowerApps", "SharePoint", "SomethingElse", null]

我的尝试: https://codepen.io/bkdigital/pen/MWEoLXv?editors=0012

【问题讨论】:

  • 输出中值的顺序是否重要,或者任何顺序都可以?
  • 为什么不检查索引并将其推送到新数组中?你试过了吗?
  • 您的代码不应位于链接后面。使用工具栏在您的问题中创建一个可运行的 sn-p;

标签: javascript arrays


【解决方案1】:

您可以将.flatMap()Set 一起使用。 .flatMap 允许您将每个对象的技术映射到一个结果数组,而 Set 允许您删除重复项。在optional chaining ?. 的帮助下,您还可以像这样保留null 的值(这样在访问Technologies 时它就不会抛出):

const data = [{ "id": 1, "Technologies": ["SharePoint", "PowerApps"] }, { "id": 2, "Technologies": ["SharePoint", "PowerApps", "SomethingElse"] }, { "id": 3, "Technologies": ["SharePoint"] }, { "id": 4, "Technologies": ["PowerApps"] }, { "id": 5, "Technologies": null } ];

const res = [...new Set(data.flatMap(obj => obj?.Technologies))];
console.log(res);

【讨论】:

    【解决方案2】:
    [...new Set(
      data
        .map(v => Array.isArray(v.Technologies) ? v.Technologies : [v.Technologies])
        .reduce((t, v) => [...t, ...v], [])
    )];
    

    【讨论】:

      【解决方案3】:

      我试图通过 JS 来解决这个问题。这是我的代码:

      const data = [{
                  "id": 1,
                  "Technologies": ["SharePoint", "PowerApps"]
              }, {
                  "id": 2,
                  "Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
              }, {
                  "id": 3,
                  "Technologies": ["SharePoint"]
              }, {
                  "id": 4,
                  "Technologies": ["PowerApps"]
              }, {
                  "id": 5,
                  "Technologies": null
              }]
              const distintValues = [];
              for (let element of data) {
                  if (element.Technologies != null) {
                      for (let elem of element.Technologies) {
                          if (!distintValues.includes(elem)) {
                              distintValues.push(elem);
                          }
                      }
                  }
              }
              console.log(distintValues);

      【讨论】:

        【解决方案4】:

        在您的尝试中,您尝试使用 reduce 来做到这一点,所以我会这样做

        var data = [{
            "id": 1,
            "Technologies": ["SharePoint", "PowerApps"]
          },
          {
            "id": 2,
            "Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
          },
          {
            "id": 3,
            "Technologies": ["SharePoint"]
          },
          {
            "id": 4,
            "Technologies": ["PowerApps"]
          },
          {
            "id": 5,
            "Technologies": null
          }
        ];
        
        const objAsArray = Object.keys(data) // first we get the keys
          .map(key => data[key]) // then we map them to their value
        
        const technologyMap = objAsArray.reduce((acc, data) => {
          // if the entry has technologies we set the key in the accumulation object to true
          if (data.Technologies) {
            data.Technologies.forEach(tech => acc[tech] = true)
          }
          return acc;
        }, {})
        
        // at the very end we get the keys of the accumulation object
        const uniqueTechnologies =
          Object.keys(
            technologyMap
          )

        【讨论】:

          猜你喜欢
          • 2021-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-13
          • 2013-02-14
          • 2022-01-11
          • 2022-11-17
          相关资源
          最近更新 更多