patternjavascriptMinor
Transform a string into an array based on grouping rules
Viewed 0 times
groupingarrayintobasedtransformrulesstring
Problem
I've got a simple spec for defining character sets, ranges, or wildcards. I'd like to take the string and appropriately create an array based on these rules. I have a solution but I'm sure there is a better way!
Example inputs and expected outputs
My implementation:
Demo fiddle here: http://jsfiddle.net/3q25eps3/
- Single characters may be used
- Sets and ranges are enclosed in brackets
[]
- Sets are comma separated,
[1,3,S]
- Ranges are hyphenated,
[1-3]
- Sets and ranges can be combined,
[1-3,7,9-10,S]
- Wildcard character is
-and not enclosed in brackets
- Strings can contain the following characters are
A-Z0-9-.
Example inputs and expected outputs
'ABC'outputs['A', 'B', 'C']
'S[1-2]-'outputs['S', '1-2', '-']
'S[1-2]2.0[0-9][1,3,7]S'outputs['S', '1-2', '2', '.', '0', '0-9', '1,3,7', 'S']
'S[1-2,7]'outputs['S', '1-2,7']
My implementation:
function stringToArray(code) {
var exploded = code.split(''),
charGroups = [],
tempGroup = '',
inGroup = false;
while (exploded.length > 0) {
var cur = exploded.shift();
if (cur === '[') {
inGroup = true;
continue;
}
if (inGroup) {
if (cur === ']') {
inGroup = false;
charGroups.push(tempGroup);
tempGroup = '';
} else {
tempGroup += cur;
}
}
if (!inGroup) {
if (cur !== ',' && cur !== '[' && cur !== ']') {
charGroups.push(cur);
}
}
}
return charGroups;
}Demo fiddle here: http://jsfiddle.net/3q25eps3/
Solution
You could perhaps use regular expressions, provided the spec stays simple. For instance
The code uses
The pattern used will match either:
And due to the
This depends on bracket not being nested or unbalanced (it can't handle that). It's also assumes anything that's not a comma should be captured. I.e. even if the character
So it's kinda rough, and I can't guarantee it'll cover all cases, but it gives the correct output for your test cases.
function stringToArray(string) {
var segments = [];
string.replace(/(\[([^\]]+)\]|[^,])/g, function (m0, m1, m2) {
segments.push(m2 || m1); // push bracket content (m2) or single char (m1)
});
return segments;
}The code uses
replace to map/scan the string (it doesn't actually bother with replacing anything), since it accepts a callback function.The pattern used will match either:
- The content between
[and]as a contiguous string:\[([^\]]+)\]
- Single, non-comma character outside brackets:
[^,]
And due to the
g (global) flag in the pattern, it'll repeat matching until the end of the string.This depends on bracket not being nested or unbalanced (it can't handle that). It's also assumes anything that's not a comma should be captured. I.e. even if the character
@ isn't part of the spec, it'll still get treated as a "valid" character and included in the output. Similarly it'll skip over multiple commas in a row, even if such a string is invalid.So it's kinda rough, and I can't guarantee it'll cover all cases, but it gives the correct output for your test cases.
Code Snippets
function stringToArray(string) {
var segments = [];
string.replace(/(\[([^\]]+)\]|[^,])/g, function (m0, m1, m2) {
segments.push(m2 || m1); // push bracket content (m2) or single char (m1)
});
return segments;
}Context
StackExchange Code Review Q#82182, answer score: 3
Revisions (0)
No revisions yet.