patternjavascriptMinor
Generating DOM from a complex strings via arrays
Viewed 0 times
arraysgeneratingdomviafromstringscomplex
Problem
This is a revised and expanded version of Transforming complex strings into simple arrays
My function
The raw
The users are separated with "#;", but this separator is also used within each user, separating the user ID from the rest of the information. I do not need the user ID, so I am using the function (
```
function selfToArray(input, inputArray, splitter) {
var splitby = splitter || ';'
if (input.indexOf( splitby ) === -1 ) {
}
else {
var input_split_array = input.split( splitby )
if (input_split_array.length = 0) input = input.replace(/,,/g, 'dummyvalue'); //used for identifying the name later on
var arr = input.split(',#')
for(var i=0; i = 0) { //find section containing the name
arr[i] = arr[i].replace('dummyvalue',',')
if (arr[i].indexOf(" (") >= 0) { //if author name contains location, such as: Fring,, Gustavo (US - New Mexico)
author.name = arr[i].split(' (')[0]
author.location = arr[i].split(' (')[1]
}
else {
author.name = arr[i][0]
}
}
else if (arr[i].indexOf("@") >= 0) { //find section with email
author.email = arr[i]
author.sip = arr[i]
author.username = arr[i].split('@')[0].toLowerCase()
}
else if (arr[i
My function
grabPerson turns strings of user information from multiple users to "business cards" on my webpage, via an array containing the information needed: Name, username and location.The raw
userinfo string (userinfo_raw) looks like this:1074;#Fring,, Gustavo (US - New Mexico),#i:0ǵ.t|adfs|gfring,#gfring@LPH.com,#gfring@lph.com,#Fring,, Gustavo (US - New Mexico);#11903;#Rodarte-Quaylet,, Lydia (US - Houston),#i:0#.w|atrema\lrquaylet,#lrquaylet@madrigal.com,#,#,, Rodarte-Quaylet,, Lydia (US - Houston)The users are separated with "#;", but this separator is also used within each user, separating the user ID from the rest of the information. I do not need the user ID, so I am using the function (
selfToArray) to separate the user ID from the rest of the data.```
function selfToArray(input, inputArray, splitter) {
var splitby = splitter || ';'
if (input.indexOf( splitby ) === -1 ) {
}
else {
var input_split_array = input.split( splitby )
if (input_split_array.length = 0) input = input.replace(/,,/g, 'dummyvalue'); //used for identifying the name later on
var arr = input.split(',#')
for(var i=0; i = 0) { //find section containing the name
arr[i] = arr[i].replace('dummyvalue',',')
if (arr[i].indexOf(" (") >= 0) { //if author name contains location, such as: Fring,, Gustavo (US - New Mexico)
author.name = arr[i].split(' (')[0]
author.location = arr[i].split(' (')[1]
}
else {
author.name = arr[i][0]
}
}
else if (arr[i].indexOf("@") >= 0) { //find section with email
author.email = arr[i]
author.sip = arr[i]
author.username = arr[i].split('@')[0].toLowerCase()
}
else if (arr[i
Solution
General notes
-
Consistency, please. JavaScript is typically
-
You're missing a lot of semicolons. I already mentioned it in a previous review, but I'd really just add those semis even if the code can run without them. Again, the automatic semicolon insertion is more of a crutch for lazy code than syntactic sugar.
About
-
The name is sort of strange. What's
-
Your
-
Or, keep the current comparison, and just return right away. Again, no need for an
-
The typical way to set a default value for an argument is to reuse the argument's name, rather than make a new variable. It helps readability. So:
By the way, I'd probably call it
-
Then again, I doubt you'll ever need to pass a custom delimiter. The rest of the code is tailored to some very specific data. It looks for
-
Overall, I'm wondering why you need to pass an array to this function. It can just return one, all on its own. This isn't C where you need to pass pointers to pointers and stuff like that. To have any function modify its input is pretty iffy unless there's a really, really good reason. And I can't think of any since you can just handle the array it returns however you want (e.g. concat it to another array or something). String in, array out, period.
About
You're using some fragile magic here, it seems. You assume the name part will always contain
If there's any sort of logic to the data you're dealing with, the "rows" will always contain the same sort of information in the same order. In this case the order appears to be:
If indeed that's the pattern (and I'll assume here that it is), you could just convert an input string to an array of "author objects" wholesale, and skip the
For your example, it returns:
(p.s. there's a backslash in Lydia's login-info, which I think is supposed to be a pipe character
As menti
-
Consistency, please. JavaScript is typically
camelCase (and PascalCase for constructors). You do use that, but you also use underscored_names here and there. Please pick one style - preferably the JS standard one - and stick to it.-
You're missing a lot of semicolons. I already mentioned it in a previous review, but I'd really just add those semis even if the code can run without them. Again, the automatic semicolon insertion is more of a crutch for lazy code than syntactic sugar.
About
selfToArray()-
The name is sort of strange. What's
self? stringToArray would be more straight-forward although it's pretty generic and doesn't describe what kind of string it is. Still, better than selfToArray.-
Your
if..elsees are kinda funny, since you're not actually doing anything in the if blocks. Just flip the comparison around, and there's no need for an else block:if (input.indexOf( splitby ) !== -1 ) { }-
Or, keep the current comparison, and just return right away. Again, no need for an
else blockif (input.indexOf( splitby ) === -1 ) { return; }
-
The typical way to set a default value for an argument is to reuse the argument's name, rather than make a new variable. It helps readability. So:
splitter = splitter || ';';
// or, alternative syntax
splitter || (splitter = ';');By the way, I'd probably call it
delimiter or separator instead (more conventional names).-
Then again, I doubt you'll ever need to pass a custom delimiter. The rest of the code is tailored to some very specific data. It looks for
# characters, and it discards every other part of the split string. It seems to me that you won't need a function that does all those very specific things - but with something other than a semicolon as the delimiter. (And indeed you don't use the function with a custom delimiter argument.)-
Overall, I'm wondering why you need to pass an array to this function. It can just return one, all on its own. This isn't C where you need to pass pointers to pointers and stuff like that. To have any function modify its input is pretty iffy unless there's a really, really good reason. And I can't think of any since you can just handle the array it returns however you want (e.g. concat it to another array or something). String in, array out, period.
About
getAuthor()You're using some fragile magic here, it seems. You assume the name part will always contain
",," (I'd assume that that's there in case of a middle name), and that the login is always "adfs" (huh?). Oh, and that the word "dummyvalue" doesn't by chance appear anywhere else. But it might, who knows? Sure, it's very unlikely, but the code is still kludgy.If there's any sort of logic to the data you're dealing with, the "rows" will always contain the same sort of information in the same order. In this case the order appears to be:
- Name and location
- Last name
- Middle name (presumably)
- First name
- Location in parantheses
- Login (I assume)
- Secondary email? Not sure, and either way it appears optional
- Name again, apparently.
If indeed that's the pattern (and I'll assume here that it is), you could just convert an input string to an array of "author objects" wholesale, and skip the
selfToArray. A tiny internal function can handle the name/location parsing.function getAuthors(input) { // note: plural, since it returns an array
// internal function to parse the name/location
function getNameAndLocation(string) {
var parts = string.match(/([^,]*),\s*([^,]*),\s*(.*?)\s+\(([^\)]*)/);
if(!parts) {
return null; // oops, couldn't match name+location
}
return {
name: {
first: parts[3],
middle: parts[2],
last: parts[1]
},
location: parts[4]
};
}
// this replaces selfToArray()
var rows = input.split(/;#?/).filter(function (_, i) { return i % 2; });
return rows.map(function (row) {
var author = {},
parts = row.split(/,#/),
nameAndLocation = getNameAndLocation(parts[0]);
author.name = nameAndLocation.name;
author.location = nameAndLocation.location;
author.login = parts[1];
author.email = author.sip = parts[2]; // p.s. what is "sip"? Not clear.
author.username = parts[2].split('@')[0];
return author;
});
}For your example, it returns:
[
{
name: { first: 'Gustavo', middle: '', last: 'Fring' },
location: 'US - New Mexico',
login: 'i:0ǵ.t|adfs|gfring',
sip: 'gfring@LPH.com',
email: 'gfring@LPH.com',
username: 'gfring'
},
{
name: { first: 'Lydia', middle: '', last: 'Rodarte-Quaylet' },
location: 'US - Houston',
login: 'i:0#.w|atremalrquaylet',
sip: 'lrquaylet@madrigal.com',
email: 'lrquaylet@madrigal.com',
username: 'lrquaylet'
}
](p.s. there's a backslash in Lydia's login-info, which I think is supposed to be a pipe character
|, right?)As menti
Code Snippets
if (input.indexOf( splitby ) !== -1 ) { <your code> }if (input.indexOf( splitby ) === -1 ) { return; }
<your code>splitter = splitter || ';';
// or, alternative syntax
splitter || (splitter = ';');function getAuthors(input) { // note: plural, since it returns an array
// internal function to parse the name/location
function getNameAndLocation(string) {
var parts = string.match(/([^,]*),\s*([^,]*),\s*(.*?)\s+\(([^\)]*)/);
if(!parts) {
return null; // oops, couldn't match name+location
}
return {
name: {
first: parts[3],
middle: parts[2],
last: parts[1]
},
location: parts[4]
};
}
// this replaces selfToArray()
var rows = input.split(/;#?/).filter(function (_, i) { return i % 2; });
return rows.map(function (row) {
var author = {},
parts = row.split(/,#/),
nameAndLocation = getNameAndLocation(parts[0]);
author.name = nameAndLocation.name;
author.location = nameAndLocation.location;
author.login = parts[1];
author.email = author.sip = parts[2]; // p.s. what is "sip"? Not clear.
author.username = parts[2].split('@')[0];
return author;
});
}[
{
name: { first: 'Gustavo', middle: '', last: 'Fring' },
location: 'US - New Mexico',
login: 'i:0ǵ.t|adfs|gfring',
sip: 'gfring@LPH.com',
email: 'gfring@LPH.com',
username: 'gfring'
},
{
name: { first: 'Lydia', middle: '', last: 'Rodarte-Quaylet' },
location: 'US - Houston',
login: 'i:0#.w|atremalrquaylet',
sip: 'lrquaylet@madrigal.com',
email: 'lrquaylet@madrigal.com',
username: 'lrquaylet'
}
]Context
StackExchange Code Review Q#63650, answer score: 3
Revisions (0)
No revisions yet.