Skip to content

Commit

Permalink
feat: add list.sortFunc
Browse files Browse the repository at this point in the history
Adds a function to list implemented in dictu which uses quickSort
to allow custom sorting which is suuuper useful for a lot of problems.
I would have preferred to implement this is C too but there doesn't seam
to be a straight forward way to pass callbacks into c.
Using a hybrid approach would have been hacky too, but of course this approach
does duplicate the sorting logic.
  • Loading branch information
liz3 committed Jan 20, 2024
1 parent a548039 commit dc0f78a
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 0 deletions.
14 changes: 14 additions & 0 deletions docs/docs/collections/lists.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,20 @@ list1.sort();
print(list1); // [-1, 1, 2, 3, 4, 5, 10]
```

#### list.sortFunc(Func)

Sorts a list with a Custom Callback

```cs
var list1 = [[1, "Dictu"], [-1, "SomeValue"], [5, "!"], [4, "Awesome"], [2, "is"]];

print(list1); // [[1, "Dictu"], [-1, "SomeValue"], [5, "!"], [4, "Awesome"], [2, "is"]];
list1.sortFunc(def(a,b) => a[0] - b[0]);

print(list1); // [[-1, "SomeValue"], [1, "Dictu"], [2, "is"], [4, "Awesome"], [5, "!"]]
```

```cs
var list1 = ["zebra", "cat", "dino", "pig"];

Expand Down
30 changes: 30 additions & 0 deletions src/vm/datatypes/lists/list-source.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,36 @@
" return temp;\n" \
"}\n" \
"\n" \
"def sortFunc(list, func) {\n" \
" if(list.len() < 2) {\n" \
" return;\n" \
" }\n" \
" const partition = def (arr, start, end) => {\n" \
" const pivot = arr[end];\n" \
" var i = start - 1;\n" \
" for(var t = start; t <= end-1; t+= 1) {\n" \
" if(func(pivot, arr[t]) > 0) {\n" \
" i+= 1;\n" \
" const temp = arr[i];\n" \
" arr[i] = arr[t];\n" \
" arr[t] = temp;\n" \
" }\n" \
" }\n" \
" const temp = arr[i+1];\n" \
" arr[i+1] = arr[end];\n" \
" arr[end] = temp;\n" \
" return i + 1;\n" \
" };\n" \
" const quickSort = def(arr, start, end) => {\n" \
" if(start < end) {\n" \
" const p = partition(arr, start, end);\n" \
" quickSort(arr, start, p - 1);\n" \
" quickSort(arr, p + 1, end);\n" \
" }\n" \
" };\n" \
" quickSort(list, 0, list.len()-1);\n" \
"}\n" \
"\n" \
"def filter(list, func=def(x) => x) {\n" \
" const temp = [];\n" \
"\n" \
Expand Down
30 changes: 30 additions & 0 deletions src/vm/datatypes/lists/list.du
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,36 @@ def map(list, func) {
return temp;
}

def sortFunc(list, func) {
if(list.len() < 2) {
return;
}
const partition = def (arr, start, end) => {
const pivot = arr[end];
var i = start - 1;
for(var t = start; t <= end-1; t+= 1) {
if(func(pivot, arr[t]) > 0) {
i+= 1;
const temp = arr[i];
arr[i] = arr[t];
arr[t] = temp;
}
}
const temp = arr[i+1];
arr[i+1] = arr[end];
arr[end] = temp;
return i + 1;
};
const quickSort = def(arr, start, end) => {
if(start < end) {
const p = partition(arr, start, end);
quickSort(arr, start, p - 1);
quickSort(arr, p + 1, end);
}
};
quickSort(list, 0, list.len()-1);
}

def filter(list, func=def(x) => x) {
const temp = [];

Expand Down
1 change: 1 addition & 0 deletions tests/lists/import.du
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import "remove.du";
import "reverse.du";
import "slicing.du";
import "sort.du";
import "sortFunc.du";
import "splice.du";
import "subscript.du";
import "toBool.du";
Expand Down
24 changes: 24 additions & 0 deletions tests/lists/sortFunc.du
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* sortFunc.du
*
* Testing list sorting with custom callback
*/
from UnitTest import UnitTest;
class A {
init(var name, var n) {}
}

class TestListSortFunc < UnitTest {
testListSortCallback() {
var list1 = [[1, "Dictu"], [-1, "SomeValue"], [5, "!"], [4, "Awesome"], [2, "is"]];
list1.sortFunc(def(a,b) => a[0] - b[0]);
this.assertEquals(list1, [[-1, "SomeValue"], [1, "Dictu"], [2, "is"], [4, "Awesome"], [5, "!"]]);
}
testListSortCallbackClass() {
var list = [A("T", 10), A("U", 15), A("C", 5), A("D", 1), A("I", 3)];
list.sortFunc(def(a,b) => a.n - b.n);
this.assertEquals(list.map(def (entry) => entry.n), [1, 3, 5, 10, 15]);
this.assertEquals(list.map(def (entry) => entry.name), ["D", "I", "C", "T", "U"]);
}
}
TestListSortFunc().run();

0 comments on commit dc0f78a

Please sign in to comment.