hrn
hrn

Reputation: 111

How to create/merge object from splitted string array in TypeScript?

I have an array of objects like below;

const arr1 = [
  {"name": "System.Level" },
  {"name": "System.Status" },
  {"name": "System.Status:*" },
  {"name": "System.Status:Rejected" },
  {"name": "System.Status:Updated" }
]

I am trying to split name property and create an object. At the end I would like to create an object like;

{
  "System.Level": true,
  "System.Status": {
    "*": true,
    "Rejected": true,
    "Updated": true
  }
}

What I have done so far;

transform(element){
  const transformed = element.split(/:/).reduce((previousValue, currentValue) => {
    previousValue[currentValue] = true;
  }, {});
  console.log(transofrmed);
 }

const transofrmed = arr1.foreEach(element => this.transform(element));

The output is;

{System.Level: true}
{System.Status: true} 
{System.Status: true, *: true}
{System.Status: true, Rejected: true}
{System.Status: true, Updated: true}

It is close what I want to do but I should merge and give a key. How can I give first value as key in reduce method? Is it possible to merge objects have same key?

Upvotes: 1

Views: 596

Answers (2)

Ori Drori
Ori Drori

Reputation: 192016

Use Array.reduce() on the list of properties. After splitting the path by :, check if there is second part. If there is a second part assign an object. Use object spread on the previous values, because undefined or true values would be ignored, while object properties would be added. If there isn't a second part, assign true as value:

const array = [{ name: "System.Level" }, { name: "System.Status" }, { name: "System.Status:*" }, { name: "System.Status:Rejected" }, { name: "System.Status:Updated" }];

const createObject = (arr) => 
  arr.reduce((r, { name }) => {
    const [first, second] = name.split(':');
    
    r[first] = second ? { ...r[first], [second]: true } : true;
    
    return r;
  }, {});
    
console.log(createObject(array));

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386654

You could reduce the splitted keys adn check if the last level is reached, then assign true, otherwise take an existent object or a new one.

const
    array = [{ name: "System.Level" }, { name: "System.Status" }, { name: "System.Status:*" }, { name: "System.Status:Rejected" }, { name: "System.Status:Updated" }],
    object = array.reduce((r, { name }) => {
        var path = name.split(':');
            last = path.pop();
        path.reduce((o, k) => o[k] = typeof o[k] === 'object' ? o[k] : {}, r)[last] = true;
        return r;
    }, {});
    
console.log(object);

Upvotes: 1

Related Questions