Reputation: 49
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
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
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
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
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