Syed Abbas
Syed Abbas

Reputation: 49

split an Js object into array

I have an object and I need to split the values into an array like below

Ex: {firstName1: "Tom", lastName1: "Jerry", firstName2: "Stuart", lastName2: "Little"}

I want the output to be like

[{fName: "Tom", lName: "Jerry"},
{fName: "Stuart", lName: "Little"}]

I can do this like

      let persons= new Array<Person>(); //Assume Person is a Typescript class
      let p1 = new Person(); 
      p1.fName= data.firstName1;
      p1.lName= data.lastName1;
      persons.push(p1);
      let p2= new Person(); 
      p2.fName= data.firstName2;
      p2.lName= data.lastName2;
      persons.push(p2);

I'm looking for an optimized/recommended way of achieving this.

Upvotes: 0

Views: 130

Answers (4)

pilchard
pilchard

Reputation: 12911

Update Reduce time complexity by avoiding nested iterations

const combined = {firstName1: "Tom", lastName1: "Jerry", age1: 101, firstName2: "Stuart", lastName2: "Little", age2: 15, petName2: "dog"};

const personMap = Object.entries(combined).reduce((acc, [k, v]) => {
   const pNum = k.match(/[0-9]+$/)[0];
   const normalKey = k.slice(0, (k.length - pNum.length));
   
   const match = acc.get(pNum),
          attr = {[normalKey]: v};
        match ?
          Object.assign(match, attr) :
          acc.set(pNum, {...attr});
          
   return acc;
}, new Map());

const refactored = [...personMap.values()].map(p => ({...p}));

console.log(refactored);

You can use a .reduce() on the keys of the initial object and generate the lastName key from the firstName to avoid ordering problems.

const combined = {firstName1: "Tom", lastName1: "Jerry", firstName2: "Stuart", lastName2: "Little"};

const refactored = Object.keys(combined).reduce((a, k) => {
    if (k.startsWith('firstName')){
      a.push({fName: combined[k], lName: combined[k.replace('firstName', 'lastName')]});
    }
   return a;
  }, []);
  
  console.log(refactored);

You can generalize this for any number of attributes and pass an array of attributes to map to the new array.

const combined = {firstName1: "Tom", lastName1: "Jerry", age1: 101, firstName2: "Stuart", lastName2: "Little", age2: 15};
const attributes = ['firstName', 'lastName', 'age'];

const refactored = Object.keys(combined).reduce((a, k) => {
    if (k.startsWith('firstName')){
      const p = attributes.reduce((b, attr) => (b[attr] = combined[k.replace('firstName', attr)], b), {});
      a.push({...p});
    }
   return a;
  }, []);
  
  console.log(refactored);

Or for an arbitrary number of attributes .filter the keys of the object by personNumber.

const combined = {firstName1: "Tom", lastName1: "Jerry", age1: 101, firstName2: "Stuart", lastName2: "Little", age2: 15, petName2: "dog"};

const refactored = Object.keys(combined).reduce((a, k) => {
    if (k.startsWith('firstName')){
      const pNum = k.replace('firstName', '');
      const p = Object.keys(combined)
          .filter(k => k.endsWith(pNum))
          .reduce((b, attr) => (b[attr.replace(pNum, '')] = combined[attr], b), {});
      a.push({...p});
    }
   return a;
  }, []);
  
  console.log(refactored);

Upvotes: 1

Eka Cipta
Eka Cipta

Reputation: 229

let obj = {firstName1: "Tom", lastName1: "Jerry", firstName2: "Stuart", lastName2: "Little"}
let keysArr = Object.keys(obj)
let valueArr = Object.values(obj)

let result = []

keysArr.map((x, i) => {
  if(x.indexOf('first') != -1){
    result.push({ fName: valueArr[i], lName: valueArr[i+1] })
  }
})

console.log(result)

Upvotes: 0

Surya Kavutarapu
Surya Kavutarapu

Reputation: 136

let requiredObject  = [];
let firstNames = []; 
let lastNames = [];
let inputObject = {firstName1: "Tom", lastName1: "Jerry", firstName2: "Stuart", lastName2: "Little"}
firstNames = Object.keys(inputObject).filter(each => each.includes('firstName'));
lastNames = Object.keys(inputObject).filter(each => each.includes('lastName'));
for(var i = 0; (firstNames.length > i &&  lastNames.length > i); i++) {
  var data = {};
  data.fName = inputObject[firstNames[i]];
  data.lName = inputObject[lastNames[i]]
  requiredObject.push(data);
}

console.log(requiredObject);

Upvotes: 2

Chintan Dhandhusariya
Chintan Dhandhusariya

Reputation: 41

How about this?

let persons= new Array<Person>();
let person = {}; //Not familiar with typescript much. Not sure if it would be {} or new Person();

Object.keys(data).forEach((key,index)=>{
    if(index%2 == 0) {
        //firstName
        person.fName = data[key];
    } else {
        //lastName
        person.lName = data[key];
        persons.push(person);
        person = {}; // or new Person();
    }
});

Upvotes: 1

Related Questions