Dataview: How to sort after numbers with seperators?

I hope this question wasn’t asked already. I searched the forum, but didn’t find anything similar to my issue.

Setup

I use a vague Zettelkasten-System in my notes. Each note begins with an index number:

1
1.1
1.2
1.2.1
...
74.1.1
74.1.2
...
74.1.10

I now want to have an Index note with a Dataview-Table. The entries should be sorted according to their Index-Number.

This is my current dataview query:

TABLE Typ, Thema, Status, URL, Permanent_Copy
WHERE Typ
SORT (file.name) ASC

Problem

SORT does not sort like this

74.1.1
74.1.2
74.1.10

but instead

74.1.1
74.1.10
74.1.2

Things I have tried

I tried to add an aditional entry

Index: $Indexnumber

because I thought it was only an issue in file names. Didn’t help. I tried different separators aside from “.”, but also the same result. In my normal file list in the sidebar the sorting is correct.
My question therefor would be: How do I achieve the same sorting as Obsidian does in the file list in the sidebar in my dataview query?

To start, read this: Dataview does not sort files by name - #2 by mnvwvnm

The point is: you have “strings”, not “numbers”.

What this means? You have more “content” in the title?

If your titles are only in the format you wrote above (without more words), then you have a “rule” and we can use a tricky way to achieve the wanted sort. If more words… well, depends. (maybe using a field “index” number)

1 Like

Thanks for your fast reply. The note title has more content.

74.1 Title ABC
74.1.1 Title DEF
74.1.2 Title GHI

I can try

SORT number(split(file.name, "\.")[0]) ASC

with an additional Index-Key, but it looks like it only works when I have only one “.”? I don’t have the experience to adapt it to a possible infinite amount of dots. I probably have to sort it first for the first level (e.g. 74.), then sort for second (.1.) and then for the third (.2), right?

Let’s say you use the field index: 73.8.1 instead of the file name.

I don’t know how to do it for an “infinite amount of dots” in DQL, only for a defined number of dots (maybe any JS expert can help in dvjs side).

So, for 2 dots (3 groups of numbers), you can use:

SORT number(split(index, "\.")[0]) ASC, number(split(index, "\.")[1]) ASC, number(split(index, "\.")[2]) ASC

2 Likes

This works! Thanks for your help.

It would be nice to have a solution that works with an indefinite amount of separators, but for the moment, I can adapt just this manually on the go. I guess at some point I will have enough hierarchies to work with.

You can do that with DataviewJS query, but it’s significantly more verbose than @mnvwvnm 's tidy one.

Split the index number into blocks, and turn those into blocks of 1000, and turn the final number into an integer. So 1.2.3 would end up as 1002003. That way you can numerically sort them.

```dataviewjs

function convertToNumericIndex (name) {
    // Split by space to get the index number
    let index = name.split(' ')[0]
    // Split the index on '.' to get an array of parts
    index = index.split('.')
    // Turn the index into an integer padded by thousands
    return index
      .map((x, i) => +x * Math.pow(1000,  index.length - i))
      .reduce((curr, prev) => curr + prev)
}

dv.table([], dv.pages()
  .sort(x => convertToNumericIndex(x.file.name), 'asc')
  .map(page => [page.file.name, page.file.link]))
```
3 Likes

Ok, now something weird is happening. It sorts everything in the right order, but only shows notes with and index with two dots or more.

Notes with an index like 74.1or 74 don’t show up. When I remove the sorting from the query, they are back again.

Do I need to add a sorting entry before the split-index-sorting for Index with 1 or 0 dots?

The point is:

index: 23
// 
index: 35.1
//
index: 71.2.2
  • first and second cases are numbers, not strings
  • third case is a string
  • split() works with strings, not with numbers.

So, applying the split() to a number will exclude that cases.

How to solve this?

Before any other more complicated solution, try replace in the query the index field by file.name and check the results:

SORT number(split(file.name, "\.")[0]) ASC, number(split(file.name, "\.")[1]) ASC, number(split(file.name, "\.")[2]) ASC
1 Like

yes, that works. Sorry, I didn’t think of the difference between strings and numbers.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.