Thrillseeker 10-01-2011, 08: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, 08: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, 09: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, 09: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, 10: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, 10: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-01-2011, 11:23 PM 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-01-2011, 11:32 PM 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-01-2011, 11:34 PM 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-01-2011, 11:37 PM 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, 12: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, 01: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.
|
|