Source language: Translate to:

Sort function

Questions and information about using VBScript and JavaScript in NeoBook functions

Moderator: Neosoft Support

Sort function

Postby dpayer » Mon Feb 13, 2012 2:58 pm

I want to develop a function to sort lists (alphabetically).

JScript has a function for this when you have your list as an array.

http://www.javascriptkit.com/javatutors/arraysort.shtml

The code below takes a NB variable [textlist] formated as a CSV with each value surrrounded by quotes and formats an array variable nameed textarray. It uses the formatting shown in the 2nd example here:

http://www.w3schools.com/js/js_obj_array.asp

The JScript function is called sort and it is called by appending it to the array's name. In my case: textarray.sort() . There is another function that reverses the order of an array: textarray.reverse

I call this function, but it does not sort. The variables can be re imported into NB and displayed but the order of the list has not changed.

Can anyone see my error? Does the .sort function not work in this circumstance?

Sort List Function
Code: Select all
var textlist=nbGetVar( "textlist" );
var textarray=new Array(textlist);
var reversesort=new Array(textlist);

textarray.sort();
reversesort.sort();
reversesort.reverse();

nbSetVar ( "textlist3", textarray );
nbSetVar ( "reversesort", reversesort );

nbsetvar ("text", textlist)


There is no JScript error. There is no NB [lasterror].

In the last line I reimport the textlist jscript variable into NB variable by a new name. This variable contains the right data and can be displayed.

David P.
User avatar
dpayer
 
Posts: 1383
Joined: Mon Apr 11, 2005 5:55 am
Location: Iowa - USA

Postby Gaev » Mon Feb 13, 2012 4:06 pm

DavidP:

Try this ...
Code: Select all
var textlist=nbGetVar( "textlist" );
var textarray=new Array(textlist);
var reversesort=new Array();  //probably not  needed

sortedArray = textarray.sort();
reversesort = sortedArray.reverse();

nbSetVar ( "textlist3", textarray );
nbSetVar ( "reversesort", reversesort );

nbsetvar ("text", textlist);

Not tested by me ... but shows how to use .sort and .reverse methods on array objects.
User avatar
Gaev
 
Posts: 3734
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Postby dpayer » Tue Feb 14, 2012 7:18 am

Gaev wrote:DavidP:

Try this ...
Code: Select all
var textlist=nbGetVar( "textlist" );
var textarray=new Array(textlist);
var reversesort=new Array();  //probably not  needed

sortedArray = textarray.sort();
reversesort = sortedArray.reverse();

nbSetVar ( "textlist3", textarray );
nbSetVar ( "reversesort", reversesort );

nbsetvar ("text", textlist);

Not tested by me ... but shows how to use .sort and .reverse methods on array objects.


Thanks Gaev, I see your logic in this: assign the result of the function to a variable and use that. I had understood the function to be one that sorted the existing array and replaced its content order with the new order.

I did try your suggestion but I seem to get the same result. I try to pop up a msgbox / alert in the function but it doesn't seem to work as a vbscript msgbox does. I wonder if JScript requires the browser to be a foundation to do its work.

Again, thanks for your contribution to this learning experience!

David
User avatar
dpayer
 
Posts: 1383
Joined: Mon Apr 11, 2005 5:55 am
Location: Iowa - USA

Postby Gaev » Tue Feb 14, 2012 9:16 am

DavidP:
I did try your suggestion but I seem to get the same result. I try to pop up a msgbox / alert in the function but it doesn't seem to work as a vbscript msgbox does. I wonder if JScript requires the browser to be a foundation to do its work.

Start with something basic like ...
Code: Select all
var originalList = new Array("Banana", "Orange", "Apple", "Mango");
alert(originalList);
sortedList = originalList.sort();
alert(sortedList);

When that works, replace the in-line hard coded array with the value passed in the function ...
Code: Select all
var passedText=nbGetVar( "textlist" );
alert(passedText);
var originalList = new Array(passedText);
alert(originalList);
sortedList = originalList.sort();
alert(sortedList);

Post the results of these two tests here ... so we can zoom in on the problem.
User avatar
Gaev
 
Posts: 3734
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Postby Gaev » Tue Feb 14, 2012 12:55 pm

DavidP:

Tried this ... and it works ...
Code: Select all
var passedText = nbGetVar( "nbTextList" );
nbSetVar('answer1',passedText);
originalList = passedText.split(",");
nbSetVar('answer2',originalList);
ListLen = originalList.length;
nbSetVar('answer3',ListLen);
sortedList = originalList.sort();
nbSetVar('answer4',sortedList);
reversedList = sortedList.reverse();
nbSetVar('answer5',reversedList);
I setup the above in a JScript function called gkTest4DavidP.

nbTextList is the content of a Text Entry Box ... content is something like "Cherry","Apple","Peach","Banana"

answer1 to answer5 are other Text Entry Boxes.

Just have a Button which does ...
Code: Select all
Call "gkTest4DavidP"
... and you are good to go.
User avatar
Gaev
 
Posts: 3734
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Postby dpayer » Tue Feb 14, 2012 1:42 pm

Gaev wrote:Start with something basic like ...
Code: Select all
var originalList = new Array("Banana", "Orange", "Apple", "Mango");
alert(originalList);
sortedList = originalList.sort();
alert(sortedList);

When that works, replace the in-line hard coded array with the value passed in the function


Good suggestion. Here is a complicating point. Tony Kroos pointed out in this post:
http://neosoftware.com/forum/viewtopic.php?t=19166
That the javascript alert box doesn't work in NB. It is a javascript syntax intended for the browser. NB uses JScript which executes via Windows Script Host (WSH) engine. To get that to launch, this syntax is required:

Code: Select all
var MsgBox=new ActiveXObject("wscript.shell")
MsgBox.Popup ("It works!")


Now, when I do that and apply your method, it does alert with the original array. I then see that you must create a new function for the next popup box to show the sorted array as you cannot simply call MsgBox.Popup again.

Having done that, I see the sort works. This tells me I will likely have to add entries to the array programatically one by one instead of defining a string to be an array (even if it is properly formated as an array should be - values surrounded by quotes). Somehow they are not the same thing. This will require looping through and then pulling those variables from the NB side into the script function.

Thanks for your help Gaev.

David P.
User avatar
dpayer
 
Posts: 1383
Joined: Mon Apr 11, 2005 5:55 am
Location: Iowa - USA

Postby Gaev » Tue Feb 14, 2012 1:54 pm

DavidP:

Please check my follow up post ... which I did after I realized you were trying to Call the (non visual) JScript function (and not deploy it in a Browser Object).

This tells me I will likely have to add entries to the array programatically one by one instead of defining a string to be an array (even if it is properly formated as an array should be - values surrounded by quotes).
Note the script command ...
Code: Select all
originalList = passedText.split(",");
which takes a "delimited string" and turns it into an "Array variable" ... you can specify any "delimiter character(s)" ... I used ",".
User avatar
Gaev
 
Posts: 3734
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Postby dpayer » Tue Feb 14, 2012 1:56 pm

Gaev wrote:DavidP:
Text Entry Boxes.

Just have a Button which does ...
Code: Select all
Call "gkTest4DavidP"
... and you are good to go.


Thanks Gaev. I am working with lists of variable length (basically working with directory listings here) and numbers of lines. Because of that, I see I have to strparse the list in NB and then in the JScript side I must loop through and get the variables and then do the .sort. Your example proves a properly formed array will sort. Now I have to create my process for arrays of various sizes to be processed.

Of course, then I want to export the sorted list to NB and display. I see I can use the .join method for an array to turn the array into a string. I was trying to pass an array back to NB as a simple variable. I can see now that won't work.

Again, many thanks for helping me see my way through this.

David P.
User avatar
dpayer
 
Posts: 1383
Joined: Mon Apr 11, 2005 5:55 am
Location: Iowa - USA

Postby David de Argentina » Tue Feb 14, 2012 2:05 pm

Hi DavidP,

Perhaps this plugin could be useful for you:

http://www.neosoftware.com/neobook/modu ... =5&lid=117

My devaluated cent,
David de Argentina
User avatar
David de Argentina
 
Posts: 1560
Joined: Mon Apr 04, 2005 4:13 pm
Location: Buenos Aires, Argentina

Postby Gaev » Tue Feb 14, 2012 2:29 pm

DavidP:
I am working with lists of variable length (basically working with directory listings here) and numbers of lines. Because of that, I see I have to strparse the list in NB and then in the JScript side I must loop through and get the variables and then do the .sort.

You might be missing the point ... the .split method will take a comma separated string variable and build an array variable from it ... so you can just pass one comma separated string to the function from NeoBook ... let the JScript do the array building ... with one .split(",")

And on the return journey, it looks like nbSetVar will convert a JScript array variable to a comma seaparated string variable for you.
User avatar
Gaev
 
Posts: 3734
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Postby dpayer » Tue Feb 14, 2012 4:12 pm

Gaev wrote:DavidP:
I am working with lists of variable length (basically working with directory listings here) and numbers of lines. Because of that, I see I have to strparse the list in NB and then in the JScript side I must loop through and get the variables and then do the .sort.

You might be missing the point ... the .split method will take a comma separated string variable and build an array variable from it ... so you can just pass one comma separated string to the function from NeoBook ... let the JScript do the array building ... with one .split(",")

And on the return journey, it looks like nbSetVar will convert a JScript array variable to a comma seaparated string variable for you.


Yes, I had made that earlier post before reading your post.

Here is my latest effort at doing a sort of a list:

Code: Select all
var textlist=nbGetVar( "textlist" );
var textlistarray=textlist.split("`");
var sortedtextlist=textlistarray.sort();
var reversetextlist=sortedtextlist.reverse();
var textarrayjoined=sortedtextlist.join();
nbSetVar ( "textlist2", textarrayjoined ) ;
var reversetextlist=sortedtextlist.reverse();
var reversearrayjoined=reversetextlist.join();
nbSetVar ( "reversesort", reversearrayjoined ) ;


I am using the tick "`" as a delimiter. I have tested that the .sort() works. I am finding errors with the .reverse() process.

Interestingly, I am having a prob getting the nbsetvar process to push the value back into the NB pub. Using the code above, neither [textlist2], nor [reversesort] are populated as expected.
User avatar
dpayer
 
Posts: 1383
Joined: Mon Apr 11, 2005 5:55 am
Location: Iowa - USA

Postby Gaev » Tue Feb 14, 2012 7:42 pm

DavidP:
I am using the tick "`" as a delimiter.

a) Not usually a good idea to use special characters (like the tick mark) as a delimiter.

b) When you say that the tick mark is the delimiter, does your delimited separated string look like ...

"Banana"' "Apple"' "Beer"
... or ...
'Banana', 'Apple', 'Beer'

If you are trying the latter, the delimiter is the comma ... and double quotes might not be substitutable.

I have tested that the .sort() works. I am finding errors with the .reverse() process.

a) What is the error ?

b) You only send back the result of a succeeding .join ... so how can you tell it is the .reverse that is not working ?

Interestingly, I am having a prob getting the nbsetvar process to push the value back into the NB pub. Using the code above, neither [textlist2], nor [reversesort] are populated as expected.

As mentioned in the earlier post ... you may not need the .join method ... nbSetVar appears to handle Array Variables just fine ... so just try and send the contents of the Array Variables back to NeoBook.


In order to determine what does not work, you need to take this one step at a time ... when you go from "expected' to "unexpected", you have zeroed in on the problem ... so, insert nbSetVar for each new variable/array in your Javascript function ... and start with a common delimiter like the comma ... once everything works, you can change to the tick mark and see if it still works.

Some pages on the W3Schools website that will help you ...

http://www.w3schools.com/js/default.asp ... Javascript
http://www.w3schools.com/js/js_obj_array.asp ... Javascript Array Object
http://www.w3schools.com/jsref/default.asp ... Javascript Objects Reference
http://www.w3schools.com/js/js_ex_objects.asp ... Examples of Javascript Array Objects
User avatar
Gaev
 
Posts: 3734
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Postby Tony Kroos » Tue Feb 14, 2012 8:49 pm

dpayer, I cannot see any troubles you talking about. Everything works as expected.

Function:
Code: Select all
var MsgBox=new ActiveXObject("wscript.shell")

var textlist=nbGetVar("textlist");
var textlistarray=textlist.split("'");
//Now we got an array
for (i=0;i<textlistarray.length;i++)
{
MsgBox.Popup (textlistarray[i],-1,"Normal: "+i);
}
var sortedtextlist=textlistarray.sort();
//Now it's a sorted array!
for (i=0;i<sortedtextlist.length;i++)
{
MsgBox.Popup (sortedtextlist[i],-1,"Sorted: "+i);
}
nbSetVar ("textlist_sorted", sortedtextlist.join("'")) ;
var reversetextlist=sortedtextlist.reverse();
//Now it's a reversed array, check array elements numbers and content
for (i=0;i<reversetextlist.length;i++)
{
MsgBox.Popup (reversetextlist[i],-1,"Sort+rev: "+i);
}
nbSetVar ("textlist_reverse_sorted", reversetextlist.join("'")) ;
//god, everything is working and just fine!


Pub:
Code: Select all
setvar "[TextList]" "Monkey'Banana'Orange'Bar'Oil'Madrid"
Call "JsSortThisCrap"
Tony Kroos
 
Posts: 402
Joined: Thu Oct 15, 2009 3:43 pm

Postby Tony Kroos » Tue Feb 14, 2012 8:54 pm

and do not try to put an array to nbSetVar
string only! (you got one after .join)

handle arrays in for {...} like this:
Code: Select all
...
...
for (i=0;i<reversetextlist.length;i++)
{
nbSetVar ("textlist_reverse_sorted"+i, reversetextlist[i]) ;
}

now you have a neobook array
Tony Kroos
 
Posts: 402
Joined: Thu Oct 15, 2009 3:43 pm

Postby Tony Kroos » Tue Feb 14, 2012 9:43 pm

dpayer wrote:I then see that you must create a new function for the next popup box to show the sorted array as you cannot simply call MsgBox.Popup again.

Why not? Sure you can. Simply call Popup method again (look at my code above), you can do it until MsgBox object is still alive.

If you want to release an instance of object, then use delete:
Code: Select all
delete MsgBox;

And you'd better do that for each object you create, just add
delete Object_Name;
at the end of your function
Tony Kroos
 
Posts: 402
Joined: Thu Oct 15, 2009 3:43 pm

Next

Return to NeoBook Functions - VBScript & JavaScript

Who is online

Users browsing this forum: No registered users and 1 guest