Naam Famas
Naam Famas

Reputation: 124

[genie/vala]: How to Sort using a custom comparator?

genie! how to Sort an array (or list) of strings in order of descending length, and in ascending lexicographic order for strings of equal length.

my data is

  datas : array of string = { 
    "cold", "z", "bpples", "pallalala", "apples", "xccv" 
    }

Upvotes: 1

Views: 429

Answers (3)

nemequ
nemequ

Reputation: 17482

I can't help much with Genie, but in Vala it would be:

private static int main (string[] args) {
  string[] datas = new string[] { 
    "cold", "z", "bpples", "pallalala", "apples", "xccv" 
  };

  GLib.qsort_with_data<string> (datas, sizeof(string), (a, b) => GLib.strcmp (a, b));

  return 0;
}

Basically, the key is GLib.qsort_with_data. You can also use Posix.qsort like apmasell mentioned, but it's a bit more difficult.

Like apmasell and txasatonga mentioned, you could use a datatype from libgee, but unless you're already using libgee you might want to go with something from glib instead. In this case, GLib.GenericArray would be a good fit. In Vala, it would look like this:

private static int main (string[] args) {
  GLib.GenericArray<string> datas = new GLib.GenericArray<string> ();
  datas.add ("cold");
  datas.add ("z");
  datas.add ("pallalala");
  datas.add ("apples");
  datas.add ("xccv");

  datas.sort (GLib.strcmp);

  return 0;
}

One very nice thing about GLib.GenericArray is that it uses a C array as its underlying storage. If you are using regular arrays in other places in your code you can access the underlying array using the GLib.GenericArray.data field and potentially avoid copying the entire array. And, of course, it also doesn't force a dependency on libgee.

Finally, your choice of variable name… 'data' is plural, the singular of 'data' is 'datum'. I only bring it up so I have an excuse to post this:

XKCD 1429

Upvotes: 4

txasatonga
txasatonga

Reputation: 419

uses Gee 
init
    a:list of string
    a= new list of string
    a.add("aa")
    a.add("ab")
    a.add("z")
    a.add("eas")
    // ordenar alfabeticamente
    a.sort()
    // ordenar la lista según la longitud
    for var x=1 to (a.size-1)
        for var y=0 to (a.size-2)
            var v1=a[y]
            var v2=a[y+1]
            if (v1.length < v2.length)
                var r= a[y]
                a[y]=a[y+1]
                a[y+1]=r
    for var i=0 to (a.size-1)
        print a[i]

Upvotes: 2

apmasell
apmasell

Reputation: 7153

Genie and Vala's built-in array type is not very friendly since it really a C array underneath. You'd have to use C's qsort function to do it.

I would recommend you use a Gee.List instead, which has a nice sort method that takes a comparator:

var list = new Gee.List<string>();
list.add("cold");
...
list.sort((a, b) => - a.collate(b));

Here this list will be reverse sorted. By default, lexicographical collation (alphabetical order) is used. If you need an array at the end, use the to_array method.

Upvotes: 4

Related Questions