Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   NPC Scripting (https://forums.graalonline.com/forums/forumdisplay.php?f=8)
-   -   Sorting (https://forums.graalonline.com/forums/showthread.php?t=134256998)

sssssssssss 11-20-2009 08:44 AM

Sorting
 
Im trying to grab values from a dbnpc and sort them out.
The names are under this.names.NAMEHERE. I also need to pull this.names.NAMEHERE.kills. What I'm looking to do is sort the .kills from highest to lowest, pull that with the NAMEHERE, and pull only the top 5 from the sort. So it would look like:

NAMEHERE 50kills
NAMEHERE 43kills
NAMEHERE 5kills

so on and so on.
I found TGraalVar.sortbyvalue(str, str, bool), but can't seem to get it to work with this. Is there a better way? How do I go about this and with what commands?

I really wish graal.net was up. :(

Codein 11-20-2009 11:10 AM

http://forums.graalonline.com/forums...ight=Quicksort

This might help you :)

cbk1994 11-20-2009 06:24 PM

I know you can do something like

PHP Code:

temp.array = {"foo""bar""meow"};
array[
0].test 10;
array[
1].test 20;
array[
2].test 1;

temp.sortedArray = array.sortByValue("test""float"true); // last parameter is ascending/descending, others should be obvious
echo(sortedArray);
// echos "meow, foo, bar" 

If you're looking for long-term (or even short-term) storage of the data, you should look into SQLite usage. It's a lot easier and more efficient than any way to sort with GS2; it would be as simple as
Quote:

SELECT account, kills FROM kills ORDER BY kills DESC
You can also limit the amount returned without any GS2
Quote:

SELECT account, kills FROM kills ORDER BY kills DESC LIMIT 5

sssssssssss 11-20-2009 06:36 PM

I know SQLight is the way to go, but we've already got so much wrapped around this dbnpc id rather not change it all.

Now on this:
PHP Code:

temp.array = {"foo""bar""meow"};
array[
0].test 10;
array[
1].test 20;
array[
2].test 1

instead of the
PHP Code:

temp.array = {values,put,here}; 

i know i can do
PHP Code:

temp.array = this.guilds.getdynamicvarnames(); 

and that will pull them up, but what can I substitute for
PHP Code:

array[0].test 10;
array[
1].test 20;
array[
2].test 1

to pull up this.guilds.GUILDNAME.kills, and pull all the kills up? Then use that to match, what to use?

WhiteDragon 11-20-2009 07:16 PM

Quote:

Originally Posted by cbk1994 (Post 1539362)
more efficient

Not necessarily. If that field is not indexed, then it will have to do a sort on the returned rows by moving the result to a temporary table and sorting them there with an internal algorithm that may not be sufficient for your data size, which can be very, very, very expensive when you have a lot of rows. If the field is indexed, then it will be faster because the b-tree index keeps it in order during the insertion/deletion, and it is only matter of reading things sequentially at that point.

Note that the optimizer can only make use of an index on the ORDER BY if it is a composite index covering all the WHERE conditions and ORDER BY conditions.

e.x.,
PHP Code:

SELECT FROM tbl WHERE a 'value' ORDER BY bc

requires the following index: (a,b,c).

e.x.,
PHP Code:

SELECT FROM tbl WHERE a 'value' AND 'value' ORDER BY c

requires the following index: (a,b,c).



The overhead of talking to SQLite and the overhead within the engine also certainly need to be taken into account when doing something small, where it often makes things faster to just manipulate the data in GS2.

Chompy 11-20-2009 08:32 PM

Quote:

Originally Posted by cbk1994 (Post 1539362)
It's a lot easier and more efficient than any way to sort with GS2;

Stuff in text like this is debatable (see post above), but the text like this is wrong. SQLite is not easier then using f.ex. one the algorithms that WhiteDragon provided in the link that Codein provided.

coreys 11-20-2009 08:43 PM

Chompy is right. SQLite is more of a convenient, centralized way to store lots of data, it's not wise to use it just for sorting capabilities.

You just can't go wrong with quicksort. :]

cbk1994 11-20-2009 08:59 PM

Quote:

Originally Posted by WhiteDragon (Post 1539369)
post

Based on his post, it seemed obvious that he was having a lot of data to be sorted, and also that it would be at least somewhat permanent. I didn't mean to sound like I meant that SQLite was the way to go to sort all data.

Quote:

Originally Posted by Chompy (Post 1539381)
Stuff in text like this is debatable (see post above), but the text like this is wrong. SQLite is not easier then using f.ex. one the algorithms that WhiteDragon provided in the link that Codein provided.

That SQLite is more efficient isn't really debatable, it just depends on the situation. That it is easier is debatable. Again, it depends on the situation. For sorting temporary data, it's probably easier to use Quicksort or some other algorithm.

fowlplay4 11-20-2009 09:15 PM

Well here's a little example on how to use sortbyvalue, it seems tricky due to the lack of documentation but it's quite simple overall. (Didn't see cbk posted this already but oh well..)

The syntax provided by script help, edited for clarity. (On RC: /scripthelp sortbyvalue).

TGraalVar.sortbyvalue(str1, str2, boolean) - sorts an array.
str1: the variable of the array members which is compared
str2: variable type; variable type can be "string", otherwise it is sorted by floating point value
boolean: sort by ascending (I.e: 1 to 9) or not

Usage:

PHP Code:

function onCreated() {
  
// Initialize Example Array
  
temp.arr = {{"a"33}, {"b"11}, {"c"22}};
  
// Loop through Array and specify Sortvalue
  
for (temp.atemp.arr) {
    
// Stores the Number in Sortvalue
    
temp.a.sortvalue temp.a[1];
  }
  
// Sort by Value
  
temp.arr.sortbyvalue("sortvalue"nulltrue);
  
// Echo Sorted Array
  
for (temp.atemp.arr) {
    echo(
temp.a[0SPC temp.a[1]);
  }
  
/*
     Echos
     b 11
     c 22
     a 33
  */


Like you posted above you can loop through your array that you created using getdynamicvarnames, and specify the sortvalue. So instead of using temp.a[1] like I did in the example you'd use the guild's/user's kills, which can be accessed like so:

PHP Code:

function onCreated() {
  
// Initialize Array and Kills Structure
  
this.guilds = {"a""b""c"};
  
this.guilds.a.kills 100;
  
this.guilds.b.kills 300;
  
this.guilds.c.kills 50;
  
// Loop and Display Kills
  
for (temp.gthis.guilds) {
    
temp.kills this.guilds.(@temp.g).kills;
    echo(
temp."'s kills: " temp.kills);
  }



sssssssssss 11-21-2009 06:04 AM

Ok, ive got it working when it echos in the rc, but having problems showing it up in the gui.

I have this in a weapon, under clientside. Ill only be posted whats appropriate to the code needed.

PHP Code:

function onActionClientSide(cmddatadata2) {
  if (
cmd == "theAbyss"){
    
Stan_WindowText.setText(@ temp.data);
  }


To change the text on the actionclientside, using and

PHP Code:

public function Stan_Window_Leave.onAction(){
  
Stan_WindowText.setText("Top 5 in The Abyss:");
  
onCreated();
  
triggerserver("weapon"this.name"getAbyss");


to trigger the server to grab the info from the dbnpc, and this serverside
PHP Code:

function onActionServerSide(actionacton) {
  if (
temp.action == "getAbyss") {
    
triggerclient("weapon"this.name"theAbyss"this.db.getTopAbyss());
  }


Then in the dbnpc,

PHP Code:

public function getTopAbyss(){
  
// Initialize Array and Kills Structure 
  
temp.guildzname getGuildList(); 
  
// Loop and Display Kills 
  
for (temp.gtemp.guildzname) { 
    
temp.kills this.guilds.(@temp.g).kills
    
temp.data temp."'s kills: " temp.kills
  } 
  return 
temp.data;


All i can get it to show in the gui is the last of all the guilds and its kills, cant figure out why, if the echo in rc worked fine.

sssssssssss 11-21-2009 06:14 AM

Also, just to note, if i stick the "return" inside the for loop, it comes out with no value in the gui, but I can echo it in the for loop and in rc its perfectly fine.

e.g.

PHP Code:

public function getTopAbyss(){
  
// Initialize Array and Kills Structure 
  
temp.guildzname getGuildList(); 
  
// Loop and Display Kills 
  
for (temp.gtemp.guildzname) { 
    
temp.kills this.guilds.(@temp.g).kills
    
temp.data temp."'s kills: " temp.kills
    return 
temp.data;
  } 



sssssssssss 11-21-2009 06:58 PM

My problem still isnt fixed. now its only showing the first this.guilds.guildname.kills value, and not the others in the gui.
PHP Code:

public function getTopAbyss(){
  
// Initialize Array and Kills Structure 
  
temp.guildzname getGuildList(); 
  
temp.data ""
  
// Loop and Display Kills 
  
for (temp.gtemp.guildzname) { 
    
temp.kills this.guilds.(@temp.g).kills
    
temp.data.sortbyvalue("kills"nullfalse);
    
temp.data temp."'s kills: " temp.kills
    return 
temp.data;
  } 


And it's not sorting correctly. Its the same as if I didnt include the sortbyvalue at all.

fowlplay4 11-21-2009 07:40 PM

I don't think you understand what's going on, when you use sortbyvalue, added comments to show what's going on.

PHP Code:

public function getTopAbyss(){ 
  
// Initialize Array
  
temp.guildzname getGuildList();  
  
// Loop through Array 
  
for (temp.gtemp.guildzname) { 
    
// You have to assign the kills to the member in the array 
    
temp.g.kills this.guilds.(@temp.g).kills;   
  }
  
// Then you sort.
  
temp.guildzname.sortbyvalue("kills"nullfalse);
  
// Now you do stuff..
  // temp.guildzname[0] would be the guild name with the most kills, and so on.   



sssssssssss 11-21-2009 07:56 PM

I know I dont understand it. Trying to. :(

This is what I got now.

PHP Code:

public function getTopAbyss(){
  
// Initialize Array and Kills Structure 
  
temp.guildzname getGuildList(); 
  
// Loop and Display Kills 
  
for (temp.gtemp.guildzname) { 
    
temp.kills this.guilds.(@temp.g).kills
  }
  
temp.guildzname.sortbyvalue("kills"nulltrue); 
  
temp.data temp."'s kills: " temp.kills
  echo(
temp.guildzname); 


that gives a random order. If i try to
PHP Code:

echo(temp.guildzname[0]); 

it comes up empty.
Also tried temp.g.kills like in ur last example, did the exact same thing.

I get the concept, pull all guild names, run those to pull all kills, sort guild names, display. Its just not workin for me. :/

fowlplay4 11-21-2009 09:34 PM

Could you provide the test data that you are using? I've been showing you examples based on your posts and how I think the data is stored.

Also you specified true as the ascending sort boolean parameter so it's putting the guild with the least kills at the start of the array, which could be the cause of the "random" results.


All times are GMT +2. The time now is 01:47 AM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.