用 JavaScript 中的嵌套对象展平数组的第一个元素

Flattening the first element of array with nested objects in JavaScript

我把一个XML数据解析成了一个JS对象,导致所有父标签都变成了一个数组。我尝试将其展平,但我似乎无法理解递归部分。

这是嵌套对象的示例:

nestedObj: [
   {
   foo1:[ "A" ],
   foo2: [
    {
     bar1: [ "B" ],
     bar2: [ "C" ]    
    }
   ], 
   foo3: [ "D" ]
   .
   .
   .
   }
]

expectedData: {
   foo1: "A" ,
   foo2:
    {
     bar1: "B",
     bar2: "C"    
    }
   , 
   foo3: "D"
 .
 .
 .
}

这是我对代码的尝试:

function flattenArrToObj(arr) {
  for(let key in arr) {
    let val = arr[key];
    if(Array.isArray(val)) {
      arr[key] = val[0];
    } else {
     flattenArrToObj(val);
    }
  }
  return arr[0];
}

它在 bar1 和 bar2 等内部数据上工作正常,但如您所见,我仍然必须 return arr[0] 才能完成我最初想要的 - 这有点矛盾到递归的努力。对此有什么想法吗?

你可以看看数组和对象。

const
    getObject = object => Object.fromEntries(Object
        .entries(object)
        .map(([k, v]) => [k, fn(v)])
    ),
    fn = value => {
        if (Array.isArray(value)) {
            return typeof value[0] === 'object'
                ? Object.assign({}, ...value.map(getObject))
                : value.length === 1
                    ? value[0]
                    : value
        }
        return getObject(value);
    }
    source = [{ foo1: ["A"], foo2: [{ bar1: ["B"], bar2: ["C"] }], foo3: ["D"] }],
    result = fn(source); 

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

根据示例数据,每个数组都有一个值。因此使用 [0]。下面的代码使用递归、Object.fromEntries()Object.entries()的组合来遍历对象。

const nestedObj = [
   {
   foo1:[ "A" ],
   foo2: [
    {
     bar1: [ "B" ],
     bar2: [ "C" ]    
    }
   ], 
   foo3: [ "D" ]
   }
];

const arrToObj = val => {
    let vals = Array.isArray(val) ? arrToObj(val[0]) : val;
    if (typeof vals === 'object') {
        return Object.fromEntries( Object.entries( vals ).map(([k, v]) => [k, arrToObj(v)]) );
    } else {
        return vals;
    }
};

const newObj = arrToObj(nestedObj);

console.log( newObj );

/* OUTPUT
{
  "foo1": "A",
  "foo2": {
    "bar1": "B",
    "bar2": "C"
  },
  "foo3": "D"
}
*/