任意嵌套对象中的递归计数

问题描述

我正在尝试做一些数据可视化并处理这个数据集。具有任意嵌套对象的对象。我正在尝试计算键中出现不同值的次数。这只是数据集的一个片段,在原始 owns 嵌套对象深入 7 级以上。

我正在使用的示例数据集:

var companyData = [{
    company: 'Pepsico',type: 'parent',owns: [
      {
      company: 'Cheetos',type: 'chips',owns: [{
        company: 'CheezyChipCo',owns: []
      }]
      },{
        company: 'Gatorade',type: 'drink',owns: [{
          company: 'Powerade',owns: []
        }]
        },],}];

我想我必须执行递归或展平类型的操作。因此我可以将所有 type 值放入这样的数组中。

我正在努力实现的目标:

[ 'drink','drink','chips','parent' ]

我需要打开 owns 以便正确计算 type 值。我觉得有两种方法可以解决它。要么递归深入一个对象。或压平对象,使所有嵌套都在同一水平上。我可能会将 Object[keys].filter.some.reduce 结合使用。但是我对如何以及以什么顺序感到非常困惑,并且希望得到一些帮助!这是我的伪:

  1. if(对象的键类型是对象)
  2. && if (object's key === "type")
  3. 然后将该 type.value 推送到数组
  4. else if(对象键的类型 !=== 对象)
  5. 然后只返回新的排序数组

抱歉,真正的前端开发时间。我不知道这是否有意义,发布我所有失败的代码尝试是否会有所帮助。

解决方法

使用直接递归...

var companyData = [{ company: 'Pepsico',type: 'parent',owns: [{ company: 'Cheetos',type: 'chips',owns: [{ company: 'CheezyChipCo',owns: [] }] },{ company: 'Gatorade',type: 'drink',owns: [{ company: 'Powerade',],}];

function mapTypes(arr,acc = []) {
  for (const o of arr) {
    acc.push(o.type);
    if (o.owns.length > 0) {
      acc = mapTypes(o.owns,acc)
    }
  }
  return acc;
}

console.log(mapTypes(companyData));

,

你可以写一个简单的递归flatten -

const flatten = ({ type,owns = [] }) =>
  [ type,...owns.flatMap(flatten) ]
 
const input =
  [{company:'Pepsico',type:'parent',owns:[{company:'Cheetos',type:'chips',owns:[{company:'CheezyChipCo',owns:[]}]},{company:'Gatorade',type:'drink',owns:[{company:'Powerade',owns:[]}]}]}]
 
console.log(input.flatMap(flatten))

[
  "parent","chips","drink","drink"
]
,

这是我的解决方案。您可以使用 reduce 函数来实现。

var companyData = [{
    company: 'Pepsico',owns: [
      {
      company: 'Cheetos',owns: [{
        company: 'CheezyChipCo',owns: []
      }]
      },{
        company: 'Gatorade',owns: [{
          company: 'Powerade',owns: []
        }]
        },}];

    let arr = []
const formattedData = (data) => data.reduce((acc,curr) => {
   arr.push(curr.type);
  
  if (Array.isArray(curr.owns)) {
    formattedData(curr.owns)
  }
  
  return arr;
  
},[]);
  
 console.log(formattedData(companyData))