猿问

如何从 JavaScript 中的嵌套对象数组递归创建平面数组?

我想转换以下数据结构:


const data = [

  {

    regions: ['United States', 'Canada']

  },

  {

    regions: ['United States']

  },

  {

    prop1: {

      regions: ['Canada']

    }

  },

  {

    prop2: [

      {

        regions: ['Mexico', 'United States'],

        prop3: {

          regions: ['Canada']

        }

      }

    ]

  }

];

转化为以下数据结构:


['United States', 'Canada', 'United States', 'Canada', 'Mexico', 'United States', 'Canada']

为了安全起见,我希望使用 ES6 来递归地执行此操作.reduce。.map


这是我到目前为止所尝试过的,但它只深入了 2 层:


export const flattenArray = (arr: Object[], prop: string): any[] =>

  arr.reduce(

    (a, c) => [

      ...new Set([

        ...a,

        ...c.map(x => x[prop]).reduce((y, z) => [...y, ...z.map(j => j)], []),

      ]),

    ],

    []

  );

更新:我没有使用@deterjan 和他下面的解决方案。如果有人需要非.flat版本,这是他在单个函数中的解决方案.reduce


export const flatten = (obj: any, prop: string): any[] => [

  ...new Set(

    Object.keys(obj).reduce((a, c) => {

      if (c === prop) {

        if (isArray(obj[prop])) {

          return [...a, ...obj[c]];

        } else {

          return [...a, obj[c]];

        }

      } else if (isArray(obj[c])) {

        return [

          ...a,

          ...obj[c].reduce((a, c) => [...a, ...flatten(c, prop)], []),

        ];

      } else if (isObject(obj)) {

        return [...a, ...flatten(obj[c], prop)];

      } else {

        return a;

      }

    }, [])

  ),

];


console.log(flatten(data, 'regions'));


心有法竹
浏览 134回答 2
2回答

小怪兽爱吃肉

不确定这是否是您正在寻找的,但以下代码递归地将对象和数组映射到它们的“regions”键,并在每一步进行展平。function isArray(what) {    return Object.prototype.toString.call(what) === '[object Array]';}function searchObj(obj) {    return Object.keys(obj).map(key => {        if (key == "regions" && isArray(obj.regions)) return obj[key];        else if (isArray(obj[key])) return searchArray(obj[key]);        else if (typeof obj === "object") return searchObj(obj[key]);        else return [];    }).flat();}function searchArray(obj) {    return obj.map(elem => searchObj(elem)).flat();}用法:searchObj(data)> ["United States", "Canada", "United States", "Canada", "Mexico", "United States", "Canada"]Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,function(a,e){return Array.isArray(e)?a.push.apply(a,r.call(e,t-1)):a.push(e),a},[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,"flatMap",{configurable:!0,value:function(r){return Array.prototype.map.apply(this,arguments).flat()},writable:!0})

慕虎7371278

这是一个使用对象作为 json 的解决方案,然后使用正则表达式在其中进行搜索。我猜想存在其他方法以更好的方式构建正则表达式,因为我必须使用替换方法来删除引号。您可以使用一些衡量性能的工具。const data = {  sourceId: {    S: "some_string"  },  ignored: {    BOOL: false  },  stepFunctionArn: {    S: "some_string"  },  certificate: {    BOOL: true  },  infoNeeded: {    L: [      "Array"    ]  },  queuesLinks: {    M: [      "Object"    ]  },};[...JSON.stringify(data).matchAll(/(?:\"regions\"\:\[)(?:\")(.*?)(?:\")\]/gi)].reduce(function(a, v) {  a = a.concat(v[1].replace(/\"/g,"").split(','));  return a;}, [])
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答