Reputation: 506
I am having an issue where an API is giving me a long string that contains multiple items that need to be broken out into an object. Here is an example of the string:
"Child 1 First Name: Ali\nChild 1 Gender: Female\nChild 1 Hair Color: Blonde\nChild 1 Hair Style: Wavy\nChild 1 Skin Tone: Tan\nChild 2 First Name: Morgan \nChild 2 Gender: Female\nChild 2 Hair Color: Brown\nChild 2 Hair Style: Ponytail\nChild 2 Skin Tone: Light\nRelationship 1 to 2: Brother\nRelationship 2 to 1: Brother\n"
It is using \n
to break everything into multiple lines. The string is one property of a larger object being sent by the API. For some reason when I try and use the .split
method on it like (full code below) I need to use JSON.stringify
in order to get my function to even begin to work.
Here is my full code:
let rawNoteData = order.customer.note;
let data = JSON.stringify(rawNoteData);
let foo = data.split("\n").reduce(function(obj, str, index) {
let strParts = str.split(":");
obj[strParts[0].replace(/\s+/g, '')] = strParts[1];
return obj;
}, {});
console.log(foo);
This is creating really crazy looking objects that look like this:
{'"Child1FirstName': ' Arabelle\\nChild 1 Gender' }
I think my function is only working for the first instance. I am a little uncertain on how to fix this and clean up all of the crazy quotes etc going on.
My goal is to split the string into an object like so:
mongoExDoc: {
child1FirstName: "Ali",
child1Gender: "Female",
child1HairColor: "Blonde",
child1HairStyle: "Wavy",
child1SkinTone: "Tan",
child2FirstName: "Morgan",
child2Gender: "Female",
child2HairColor: "Brown",
child2HairStyle: "Ponytail",
child2SkinTone: "Light",
relationship1To2: "Brother",
relationship2To1: "Brother"
}
From there I will be combining its properties with another object being inserted into MongoDB.
Any help is GREATLY appreciated!
Upvotes: 19
Views: 31854
Reputation: 151
Something like this?
let data = 'Child 1 First Name: Ali\nChild 1 Gender: Female\nChild 1 Hair Color: Blonde\nChild 1 Hair Style: Wavy\nChild 1 Skin Tone: Tan\nChild 2 First Name: Morgan \nChild 2 Gender: Female\nChild 2 Hair Color: Brown\nChild 2 Hair Style: Ponytail\nChild 2 Skin Tone: Light\nRelationship 1 to 2: Brother\nRelationship 2 to 1: Brother\n';
let target = {};
data.split('\n').forEach((pair) => {
if(pair !== '') {
let splitpair = pair.split(': ');
let key = splitpair[0].charAt(0).toLowerCase() + splitpair[0].slice(1).split(' ').join('');
target[key] = splitpair[1];
}
});
console.dir(target);
produces an object like what you're asking for
Upvotes: 3
Reputation: 191976
I can think of 2 methods to convert the string to an object:
JSON#parse
.const str = "Child 1 First Name: Ali\nChild 1 Gender: Female\nChild 1 Hair Color: Blonde\nChild 1 Hair Style: Wavy\nChild 1 Skin Tone: Tan\nChild 2 First Name: Morgan \nChild 2 Gender: Female\nChild 2 Hair Color: Brown\nChild 2 Hair Style: Ponytail\nChild 2 Skin Tone: Light\nRelationship 1 to 2: Brother\nRelationship 2 to 1: Brother\n";
const toObject = (str) => {
const json = str.replace(/([^\:]+)\:([^\n]+)\n/g, (_, p1, p2) => {
return `"${p1.replace(/\s+/g, '')}":"${p2.trim()}",`;
});
return JSON.parse(`{${json.slice(0, -1)}}`);
};
console.log(toObject(str));
Or
const str = "Child 1 First Name: Ali\nChild 1 Gender: Female\nChild 1 Hair Color: Blonde\nChild 1 Hair Style: Wavy\nChild 1 Skin Tone: Tan\nChild 2 First Name: Morgan \nChild 2 Gender: Female\nChild 2 Hair Color: Brown\nChild 2 Hair Style: Ponytail\nChild 2 Skin Tone: Light\nRelationship 1 to 2: Brother\nRelationship 2 to 1: Brother\n";
const toObject = (str) => {
const arr = str.match(/[^\:\n]+/g);
const obj = {};
for(let i = 0; i < arr.length; i += 2) {
obj[arr[i].replace(/\s+/g, '')] = arr[i + 1].trim();
}
return obj;
};
console.log(toObject(str));
Upvotes: 1
Reputation: 9690
If order.customer.note
is your example string, then this should work:
let data = "Child 1 First Name: Ali\nChild 1 Gender: Female\nChild 1 Hair Color: Blonde\nChild 1 Hair Style: Wavy\nChild 1 Skin Tone: Tan\nChild 2 First Name: Morgan \nChild 2 Gender: Female\nChild 2 Hair Color: Brown\nChild 2 Hair Style: Ponytail\nChild 2 Skin Tone: Light\nRelationship 1 to 2: Brother\nRelationship 2 to 1: Brother\n";
//let data = JSON.stringify(rawNoteData); <-- Don't do this. order.customer.note is not an object.
let foo = data.split("\n").reduce(function(obj, str, index) {
let strParts = str.split(":");
if (strParts[0] && strParts[1]) { //<-- Make sure the key & value are not undefined
obj[strParts[0].replace(/\s+/g, '')] = strParts[1].trim(); //<-- Get rid of extra spaces at beginning of value strings
}
return obj;
}, {});
console.log(foo);
Upvotes: 16