Search code examples
javascriptrecursion

Create new Object by reading other object with recursive values


I have a object obj1 which has mapping information which is present in other as values vals. I am able to create flat object structure but recursive is not working so require help on this

const obj1 = [
  {
    mapping: "cities",
  },
  {
    mapping: "category",
    children: {
      mapping: "type",
      children: {
        mapping: "otherType",
      },
    },
  },
  {
    mapping: "age",
  },
];

const vals = [
  {
    mapping: "category",
    values: [{}],
  },
  {
    mapping: "type",
    values: [{}],
  },
  {
    mapping: "otherType",
    values: [{}],
  },
  {
    mapping: "cities",
    values: [{}],
  },
  {
    mapping: "age",
    values: [{}],
  },
];


I want expected data in below fromat


const exectedData = {
    cities: {
        values: [{}],
    },
    category: {
        values: [{}],
        children: {
            type: {
                values: [{}],
                children: {
                    otherType: {
                        values: [{}],
                    }
                }
            }
        }
    },
    age: {
        values: [{}]
    }
}

With below method i am able to create flat data but recursively data is not coming under children property



  const processItem = (config, vals) => {
    const isDataAvailable = vals.find(
      (item) => item.category === config.category,
    );

    if (isDataAvailable) {
      if (config.children) {
        processItem(config.children, vals);
      }

      const { mapping } = config;
      finalData.push({
        mapping,
        values: isDataAvailable.values,
      });
    }
  };

  config.forEach((config) => processItem(config, values));

Solution

  • You could transform your values to an object for faster update value finding and make a simple recursion:

    const obj = [
      {
        mapping: "cities",
      },
      {
        mapping: "category",
        children: {
          mapping: "type",
          children: {
            mapping: "otherType",
          },
        },
      },
      {
        mapping: "age",
      },
    ];
    
    const vals = [
      {
        mapping: "category",
        values: [{}],
      },
      {
        mapping: "type",
        values: [{}],
      },
      {
        mapping: "otherType",
        values: [{}],
      },
      {
        mapping: "cities",
        values: [{}],
      },
      {
        mapping: "age",
        values: [{}],
      },
    ];
    
    const map = vals.reduce((r, {mapping, ...item}) => (r[mapping] = item, r), {});
    
    const update = obj => {
      if(Array.isArray(obj)) return obj.forEach(update);
      if(typeof obj !== 'object') return;
      Object.values(obj).forEach(update);
      Object.assign(obj, map[obj.mapping]);
    };
    
    update(obj);
    console.log(obj);