patternjavascriptMinor
Character range generator
Viewed 0 times
rangecharactergenerator
Problem
I am working on trying to create a range function in JavaScript that imitates PERL's 'a'..'zz'.
which expands to:
And so on for every extra character you add to the end of the range( e.g zzz .... ).
I have a working implementation, However, I think that there is a more efficient - and perhaps more idiomatic - solution.
There are two things I would like answers to address:
```
function charRange( start, end ) {
var current = start;
var range = [];
range.push( current ); //Put the start directly into the range.
if ( typeof start === typeof end &&
( typeof start === "string" )) {
if ( typeof end !== "string" ) {
console.log( "ERROR: start and end must both be Strings!" );
}
}
while ( !stringEqual(current.split(""), end.split("")) ) {
current = next(current);
range.push( current );
// process.exit();
}
return range;
function stringEqual( chars, testChars ) {
var isEqual = 1;
var sum = 0;
var testSum = 0;
var i = 0;
while ( i < testChars.length ) {
// console.log(chars);
// console.log(testChars);
// console.log(i);
if ( isEqual && chars[i] !== testChars[i] ) {
isEqual = 0;
};
if ( chars[i] ) {
sum += chars[i].charCodeAt(0);
};
testSum += testChars[i].charCodeAt(0);
i++;
}
// console.log( sum + " " + testSum );
return isEqual || (sum < testSum ? 0 : 1);
}
function allAreZ( string ) {
var found = 1;
var i = 0;
while ( i < string.length ) {
if ( string[i] !== "z" ) {
found = 0;
break;
}
i++;
}
return found;
}
function findIncrem
which expands to:
- a->z
- aa->az
- ba->bz
- ...
- za->zz
And so on for every extra character you add to the end of the range( e.g zzz .... ).
I have a working implementation, However, I think that there is a more efficient - and perhaps more idiomatic - solution.
There are two things I would like answers to address:
- I would like to reduce the code size - this seems like too many lines for the problem that it solves.
- I would like improve the performance - the implementation that I have is very slow for any end string > 5 characters long.
```
function charRange( start, end ) {
var current = start;
var range = [];
range.push( current ); //Put the start directly into the range.
if ( typeof start === typeof end &&
( typeof start === "string" )) {
if ( typeof end !== "string" ) {
console.log( "ERROR: start and end must both be Strings!" );
}
}
while ( !stringEqual(current.split(""), end.split("")) ) {
current = next(current);
range.push( current );
// process.exit();
}
return range;
function stringEqual( chars, testChars ) {
var isEqual = 1;
var sum = 0;
var testSum = 0;
var i = 0;
while ( i < testChars.length ) {
// console.log(chars);
// console.log(testChars);
// console.log(i);
if ( isEqual && chars[i] !== testChars[i] ) {
isEqual = 0;
};
if ( chars[i] ) {
sum += chars[i].charCodeAt(0);
};
testSum += testChars[i].charCodeAt(0);
i++;
}
// console.log( sum + " " + testSum );
return isEqual || (sum < testSum ? 0 : 1);
}
function allAreZ( string ) {
var found = 1;
var i = 0;
while ( i < string.length ) {
if ( string[i] !== "z" ) {
found = 0;
break;
}
i++;
}
return found;
}
function findIncrem
Solution
From a once over:
-
You can merge these
into
-
I cannot understand why you would need
why can't you simply
-
Also, this, I cant see when you would need this:
Since you verify that both
-
or, you something fun like this
I am mulling about writing something far shorter with
- As a caller I would rather whether
startorendwas not a string instead of gettingERROR: start and end must both be Strings!
- Indentation! Please consider using something like jsbeautifier
-
You can merge these
var range = [];
range.push(current); //Put the start directly into the range.into
var range = [start]; //Begin with the start <- Perhaps too zen a comment- Do not keep commented out code
-
I cannot understand why you would need
while(!stringEqual(current.split(""), end.split(""))) {why can't you simply
while(current != end) {-
Also, this, I cant see when you would need this:
if ( typeof item === "number" ) {
return item++;Since you verify that both
start and end are string, this should never happen?-
allAreZ is written in a convoluted way, in this type of function ( small, and dedicated to 1 task), it is appropriate to return immediately. You could try something like function allZ( string ) {
var i = 0;
while ( i < string.length ) {
if ( string[i] !== "z" ) {
return false;
}
i++;
}
return true;
}or, you something fun like this
function allZ( string ) {
return string.split('z').length == string.length + 1;
}I am mulling about writing something far shorter with
.toString(26) To be sure zzzzzz equals 308915775, that is a lot of entries to store in array, in fact at this point it is silly to store this into an array. You would be better of writing an iterator class which provides a next() function for ranges in that size.function charRange(start, end)
{
if(typeof start != "string" ){
throw 'start must be a string';
}
if(typeof end != "string" ){
throw 'end must be a string';
}
var range = [],
current,
mapRadix = {},
mapAlphabet = {},
a = 'a'.charCodeAt(0);
for( var i = 0 ; i end ){
throw 'start must be smaller than end';
}
while(current != end ) {
range.push(number2String(current++));
}
return range;
}Code Snippets
var range = [];
range.push(current); //Put the start directly into the range.var range = [start]; //Begin with the start <- Perhaps too zen a commentwhile(!stringEqual(current.split(""), end.split(""))) {while(current != end) {if ( typeof item === "number" ) {
return item++;Context
StackExchange Code Review Q#63563, answer score: 5
Revisions (0)
No revisions yet.