使用嵌套对象展平数组

时间:2019-03-15 09:23:48

标签: javascript ecmascript-6

我有一个带有对象的数组,可以有多个子对象,这些子对象与父对象具有相同的结构,基本上只是对象嵌套。

我想知道如何才能弄平对象的结构,以便获得所有对象的ID,包括嵌套对象的ID。

例如,此结构

const data = [
  {
    id: 2,
    children: [
      {
        id: 1,
        children: []
      }
    ]
  },
  {
    id: 3,
    children: [],
  }
]

应对此扁平化

const data = [2,1,3]

我尝试过

使用Array.reduce()和对象散布语法,但是我无法完全理解执行此操作所需的逻辑。

9 个答案:

答案 0 :(得分:3)

   <input type="hidden" id="refresh" name="refresh" value="no">
   <script>
   if ($("#refresh").val() == "no")
   {
      $("#refresh").val("yes");
   }
   else
   {
      parent.location.reload(true);
   }
   </script>

答案 1 :(得分:2)

这是递归工作。循环遍历数组,并为数组中的每个元素将id推入新数组,并为子级重复该操作。

const data = [{
    id: 2,
    children: [{
      id: 1,
      children: []
    }]
  },
  {
    id: 3,
    children: [],
  }
];

console.log(flatten(data));

function flatten(data) {
  const result = [];
  recursive(data);
  return result;

  function recursive(data) {
    data.forEach(member => {
      result.push(member.id);
      recursive(member.children);
    });
  }
}

答案 2 :(得分:1)

您可以使用JSON.stringify,并为id的每个键推入一个数组:

const data = [
  {
    id: 2,
    children: [
      {
        id: 1,
        children: []
      }
    ]
  },
  {
    id: 3,
    children: [],
  }
]
const ids = [];
JSON.stringify(data, (key, val) => {
  if (key === 'id') {
    ids.push(val);
  }
  return val;
});
console.log(ids);

答案 3 :(得分:1)

您可以执行一些递归方法。

function flatArr(arr, res) {
  // iterate over the array
  arr.forEach(o => {
    // check id is present then push it into the result array
    if ('id' in o) res.push(o.id)
    // check children is present and non-empty
    // then ecursively call the function
    if (o.children && o.children.length) flatArr(o.children, res);
  })
  // return the result array(optional)
  return res;
}

console.log(flatArr(data, []));

const data = [{
    id: 2,
    children: [{
      id: 1,
      children: []
    }]
  },
  {
    id: 3,
    children: [],
  }
];

function flatArr(arr, res) {
  // iterate over the array
  arr.forEach(o => {
    // check id is present then push it into the result array
    if ('id' in o) res.push(o.id)
    // check children is present and non-empty
    // then ecursively call the function
    if (o.children && o.children.length) flatArr(o.children, res);
  })
  // return the result array(optional since it's the same array reference you are passing initially)
  return res;
}

console.log(flatArr(data, []));

答案 4 :(得分:1)

您可以使用递归。请注意,下面传递了UPDATE Lookup_Table INNER JOIN [Source2] ON [Lookup_Table].[Name] = [Source2].[Name] SET [ID_Source2] = [Source2].[ID] 的代码引用,因此我们可以直接为其arr id,而无需获取push()

return

答案 5 :(得分:1)

我不喜欢递归:)

请注意另一个Stringify答案-ILST
https://stackoverflow.com/a/55179326/295783

const data=[{id:2,children:[{id:1,children:[]}]},{id:3,children:[],}];

console.log(
  JSON.stringify(data)
    .match(/(?:"id":)(\d+)/g)
    .map(v => +v.replace(/"id":/g, ""))
)

但是,我希望有人能找到我一种方法来一视同仁地忽略未捕获的群体

答案 6 :(得分:0)

您可以使用实际ID减少对象的数组,并获取其子对象。

const
    getId = array => array.reduce(
        (r, { id, children }) => [...r, id, ...getId(children)],
        []
    ),
    data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [] }],
    ids = getId(data);
    
console.log(ids);

答案 7 :(得分:0)

您可以使用递归方法并为每个children进行迭代,并将所有id推入数组。

const data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [], } ],
      getId = (data) => data.reduce((r,{id, children}) => r.concat(id, getId(children)),[]);
console.log(getId(data));

答案 8 :(得分:0)

另一个版本。不是最漂亮,但是可以完成工作:

const data = [
    {
        id: 2,
        children: [
            {
                id: 1,
                children: []
            }
        ]
    },
    {
        id: 3,
        children: [],
    }
];
    
let mappedArray = data.map(num => [].concat(num.children.map(child => child.id)).concat(num.id));
    mappedArray = [].concat.apply([], mappedArray);

console.log(mappedArray);