简体   繁体   中英

How to re-map an array to use in Ant Design Tree

I have this code structure:

const data = [
  {
    name: 'Lebron',
    sports: 'Basketball',
  },
  {
    name: 'Durant',
    sports: 'Basketball',
  },
  {
    name: 'Federrer',
    sports: 'Tennis',
  },
  {
    name: 'Nadal',
    sports: 'Tennis',
  },
];

and I'm trying to transform it into this:

const treeData = [
  {
    title: 'Select All',
    key: 'All',
    children: [
      {
        title: 'Basketball',
        key: 'Basketball',
        children: [
          {
            title: 'Lebron',
            key: 'Lebron',
          },
          {
            title: 'Durant',
            key: 'Durant',
          },
        ],
      },
      {
        title: 'Tennis',
        key: 'Tennis',
        children: [
          {
            title: 'Federrer',
            key: 'Federrer',
          },
          {
            title: 'Nadal',
            key: 'Nadal',
          },
        ],
      },
    ],
  },
];

to use in Ant Design Tree link .

Right now my plan is to get all the sports like this:

let sports = data.map(({ sports }) => sports); 
sports = [...new Set(sports)];

but after that I have no idea on what should be my next step to achieve the treeData

const data = [
  {
    name: 'Lebron',
    sports: 'Basketball',
  },
  {
    name: 'Durant',
    sports: 'Basketball',
  },
  {
    name: 'Federrer',
    sports: 'Tennis',
  },
  {
    name: 'Nadal',
    sports: 'Tennis',
  },
];

const dataMap: Record<string, string[]> = {};
data.forEach(({ name, sports }) => {
    dataMap[sports] ??= []
    dataMap[sports].push(name)
})

const treeData = [{
    title: 'Select All',
    key: 'All',    
    children: Object.entries(dataMap).map(([sport, names]) => ({
        title: sport,
        key: sport,
        children: names.map(name => ({
            title: name,
            key: name
        }))
    }))
}]

Here's a two-steps way of get the children of your final object:

First, use a reduce to create an object of sports/children, where children matches what you have in your final output:

const middle = data.reduce((transformed, item) => {
  if (!transformed[item.sports]) {
    transformed[item.sports] = [];
  }
  transformed[item.sports].push({
    title: item.name,
    key: item.name
  });
  return transformed;
}, {});

Then map the results of the reduce function to reshape the object:

const results = Object.entries(middle).map(([key, children]) => ({
  title: key,
  key,
  children
}));

You can use .reduce() to accumulate all sports to a Map , where each sport is a key and each value for the sport is an array of associated name s. Once you have built the Map, you can use Array.from() to convert your map into your desired children array. This can be done by providing a mapping function as the second argument to Array.from(), and using it to convert each entry ( [key, value] ) pair to an object of your desired structure.

See example below:

 const data = [ { name: 'Lebron', sports: 'Basketball', }, { name: 'Durant', sports: 'Basketball', }, { name: 'Federrer', sports: 'Tennis', }, { name: 'Nadal', sports: 'Tennis', }, ]; const children = Array.from(data.reduce((m, {name, sports}) => m.set(sports, [...(m.get(sports) || []), name]) , new Map), ([key, arr]) => ({title: key, key, children: arr.map(title => ({title, key: title}))})); const treeData = [{title: 'Select All', key: 'All', children}]; console.log(treeData);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM