...

View Full Version : Removing characters from a string



Thrillseeker
10-01-2011, 09:22 PM
Hi,

So I've got an array called questions_raw


questions raw = [
["<Q1> Question",
"choice1","choice2", "choice3"],
["<Q2> Question",
"choice1","choice2", "choice3"],
...
]

And I want to list all of the questions, but not the choices/answers. So far, I've managed to list just the questions, but because another function randomly sorts them, I need to sort them back into numerical order for a separate function (displaying the questions)

I use characters (>,^) at the front to separate them into different answer types (just to explain the code)

I try this to cut each string down so that they can be sorted numerically/alphebetically -


function linearlist()
{
var list = [];
var tempStr = "";
for (var l = 0; l < 145; l++)
{
tempStr = questions_raw[l][0];
list[l] = tempStr;
}

if (list.charAt(0)== " " ) list = list.substring(3);
if (list.charAt(0)== ">" ) list = list.substring(3);
if (list.charAt(0)== "^" ) list = list.substring(3);
var sorted = list.sort();

document.Qtext2form.Qtext2.value = sorted.join("\n");
}

But it doesn't like it - because "it has no method charAt"

Any idea what i'm missing? Is it just that you have to put the [l] in every time you call a variable?

Cheers

nomanic
10-01-2011, 09:28 PM
yes list is an array which has no charAt (which is performed on a string)
list[l] is a string, on which you can perform a charAt
so just shove in [l] or whatever to specify the string inside the array

to put it another way list is say 5 strings
charAt on an array means nothing, an array has no such function
but the second item in the array say is a string
so list[2].charAt(1) means something, charAt is a function you can do on a string

but if you do add in [l] put it inside the loop so l means something



for (var l = 0; l < 145; l++) {
tempStr = questions_raw[l][0];
list[l] = tempStr;
if (list[l].charAt(0)== " " ) list[l] = list[l].substring(3);
if (list[l].charAt(0)== ">" ) list[l] = list[l].substring(3);
if (list[l].charAt(0)== "^" ) list[l] = list[l].substring(3);
}
var sorted = list.sort();

Thrillseeker
10-01-2011, 10:05 PM
Ahh nice one, that worked. Had to bypass the 'tempStr' bit too. Cheers mate

One thing though, at the moment it puts 11 before 2 (etc). I'll need to sort that out. Apart from that its spot on

nomanic
10-01-2011, 10:29 PM
you need to change your sort code like this



IV=function(x){if(typeof(x)==='number'){return Math.floor(x);}var v,as,d=0,neg=1;x='e'+x;while(true){v=d;x=x.substring(1)+'e';as=x.charCodeAt(0);d=((as>47)&&(as<58))?((v+(as-48))*10):0;if(d===0){if(as===45){neg=-1;}else{return((neg*v)/10);}}}};

list.sort(function(a, b) {return (IV(a)<IV(b));});



but change IV(a) into IV(a.substring(0,2)) or whatever for the section of string that contains the number

Thrillseeker
10-01-2011, 11:35 PM
Doesn't really work. This is what i've put in


IV=function(x){if(typeof(x)==='number'){return Math.floor(x);}var v,as,d=0,neg=1;x='e'+x;while(true){v=d;x=x.substring(1)+'e';as=x.charCodeAt(0);d=((as>47)&&(as<58))?((v+(as-48))*10):0;if(d===0){if(as===45){neg=-1;}else{return((neg*v)/10);}}}};
var sorted = list.sort(function(a, b) {return (IV(a.substring(0,1))<IV(b));});
document.Qtext2form.BoxB.value = sorted.join("\n");

(No numbers exceed 2 digits)

They just come up in a random order (15,8,3...) which is what the script seems to do when the sort function isn't working.

venegal
10-01-2011, 11:58 PM
you need to change your sort code like this



IV=function(x){if(typeof(x)==='number'){return Math.floor(x);}var v,as,d=0,neg=1;x='e'+x;while(true){v=d;x=x.substring(1)+'e';as=x.charCodeAt(0);d=((as>47)&&(as<58))?((v+(as-48))*10):0;if(d===0){if(as===45){neg=-1;}else{return((neg*v)/10);}}}};

list.sort(function(a, b) {return (IV(a)<IV(b));});




I don't much appreciate giving out this sort of cryptic code — beginners will just copy-paste it without gaining any understanding of what it actually does, and, in all honesty, what it does is horrible.

Here's the monstrosity in all its glory:


IV = function (x) {

if (typeof(x) === 'number'){
return Math.floor(x);
}

var v, as, d = 0, neg = 1;

x = 'e' + x;

while (true) {
v = d;
x = x.substring(1) + 'e';
as = x.charCodeAt(0);
d = ((as > 47) && (as < 58)) ? ((v + (as - 48)) * 10) : 0;

if (d === 0) {
if (as === 45) {
neg = -1;
}
else {
return ((neg * v) / 10);
}
}
}
};

list.sort(function(a, b) {return (IV(a) < IV(b));});


So, what does it do? It sorts strings containing integers in browser dependent (!) order by means of — brace yourself — extracting single digits, getting to their values by comparing them to an ASCII table, and reassembling them to an actual integer.

All in all, this looks like something I could have built in SpaceChem.

I've heard the suggestions that October 1st, being the farthest possible distance from April 1st, is the perfect day for dishing out a prank or two, since people will least expect it, but let's keep it sane here for a moment: That IV function does the same thing parseInt does, only worse.

So, Thrillseeker, please forget that you have ever seen this. Using a regexp to get to that number in there, your whole code can be as simple as this (assuming that the variable questions_shuffled holds the shuffled version of questions_raw):


var extractNumber = function (question) {
return parseInt(question[0].match(/\d+/)[0]);
};

questions_shuffled.sort(function (a, b) {
return extractNumber(a) - extractNumber(b);
});



I wrote before that nomanic's code sorts the array in descending order, but since function(a, b) {return (IV(a)<IV(b));} isn't a consistent comparison function, the resulting order is actually browser dependent.

Thrillseeker
10-02-2011, 12:23 AM
Thanks for clearing that up venegal

I've tried the code above, and it throws up an error "Cannot read property '0' of null".

What is 'question'? Do i need to substitute that for one of my variables? And do I need to change the 0's in the first function?

Old Pedant
10-02-2011, 12:32 AM
And I want to list all of the questions, but not the choices/answers. So far, I've managed to list just the questions, but because another function randomly sorts them, I need to sort them back into numerical order for a separate function (displaying the questions)

So why not make a *SEPARATE* array of *JUST* the questions *BEFORE* you do the sort. And just hang onto that for when you need the list of questions????


questions raw = [
["<Q1> Question",
"choice1","choice2", "choice3"],
["<Q2> Question",
"choice1","choice2", "choice3"],
...
]
var questionsOnly = [];
for ( var r = 0; r < raw.length; ++r )
{
questionsOnly.push( raw[r][0] );
}

*HAS* to be MUCH LESS work than any other solution, doesn't it?

venegal
10-02-2011, 12:34 AM
Like I said, the snippet I posted assumes that questions_shuffled holds a reference to the shuffled questions array.

Here's a full working example:



// The original questions
var questions = [
["<Q1> Question", "choice1", "choice2", "choice3"],
["<Q2> Question", "choice1", "choice2", "choice3"],
["<Q3> Question", "choice1", "choice2", "choice3"],
["<Q4> Question", "choice1", "choice2", "choice3"],
["<Q5> Question", "choice1", "choice2", "choice3"]
];
alert(questions);


// Shuffle the questions
questions.sort(function () {return Math.random() - 0.5});
alert(questions);


//Sort the questions to their original order
var extractNumber = function (question) {
return parseInt(question[0].match(/\d+/)[0]);
};
questions.sort(function (a, b) {
return extractNumber(a) - extractNumber(b);
});
alert(questions);

venegal
10-02-2011, 12:37 AM
So why not make a *SEPARATE* array of *JUST* the questions *BEFORE* you do the sort. And just hang onto that for when you need the list of questions????


That's probably the sanest advice in this thread so far. I just felt the need to rewrite nomanic's snippet, so no one stumbling on this thread having a similar sorting problem gets the idea that that's the way it's done.

Thrillseeker
10-02-2011, 01:26 AM
I see how it fits in. I'll give it another try + figure out why it didn't work first time.

Old Pedant, that would be a great idea if the questions were fixed (or if there wasn't many of em). But plan is, new ones will be added all the time. And I may well be doing a major shuffle of the order. If the script works, it'll be a much more sustainable option. Sorry for the slow learning, its been extremely helpful though. Cheers guys.

Old Pedant
10-02-2011, 02:14 AM
Your response makes no sense.

No matter *HOW* the array of questions is created, *JUST BEFORE YOU SORT IT* out of its original order, run my code. It will *AUTOMATICALLY* give you an array with *just* the questions, in the original order.

You can go get the questions via ESP for all it matters. Just be sure to plunk in that code to create questionsOnly *before* the shuffle.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum