如何从包含数组的对象数组中获取不同的值

Posted

技术标签:

【中文标题】如何从包含数组的对象数组中获取不同的值【英文标题】: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; 【参考方案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
  )

【讨论】:

以上是关于如何从包含数组的对象数组中获取不同的值的主要内容,如果未能解决你的问题,请参考以下文章

如何从自定义模型对象数组中获取特定键的值

如何从嵌套的对象数组中获取每个父级的值

获取数组中对象的值

如何获取从 Knex 返回的值(数组中的对象,即数组中的对象)

如何在 Laravel Eloquent 中获取包含数组的 JSON 对象的值?

从Mongo DB嵌套数组中获取不同的值并输出到单个数组