Dataview sort on part of property value

What I’m trying to do

I have a dataview for displaying book, This work fine.
The data comes (if possible) from the book plugin.
Now I’m looking a way to sort the book on the last name of the author. As Lastname does not exists I need to extract the last woord from the property Schrijver.


tags:

  • epub
    Titel: De boodschapper
    Schrijver: Kader Abdolah
    Achternaam: Abdolah
    Serie:
    Serienumber:
    Categorie: Fiction
    Uitgever: Singel Uitgeverijen
    Paginas: 244
    Taal: NL
    Bindwijze: Epub
    Cover: “[[De boodschapper - Kader Abdolah.jpeg]]”
    Gekocht: true
    Gelezen: true
    calibreURL:
    cssclasses:
  • page-90

	Table 
	WITHOUT ID 
	link(file.name, Titel) AS Titel, embed(link(cover, "150")) AS Cover, 
	choice(gekocht , "✅", "✘") as Gekocht,	 Schrijver
	FROM "02 - Multimedia/02 - Boeken/Boeken"
	
	WHERE (Achternaam >= "A" and Achternaam <="F")
	Sort Achternaam, Titel ASC

Things I have tried

I have created an extra property called Achternaam, so the datives works. But this is a lot of work adding something extra.

I think it could be possible with Dataviewjs, but I don’t understand it. Tried it without luck

	// create table 
	dv.table(["Schrijver", "Achternaam"],
		// get the pages
		dv.pages('"02 - Multimedia/02 - Boeken/Boeken"')
		//.where(p )......
		//.sort(page => page.file.cday, "desc")
	);

Any advice would be helpful.

can you sort by SORT split(Schrijver," ")[1] ASC ?
https://blacksmithgu.github.io/obsidian-dataview/reference/functions/#splitstring-delimiter-limit

1 Like

I’d use the following to get the last name of the author: slice(split(Schrijver, " "), -1)

This will allow multiple forenames, but only use the last surname. So from John Ronald Reuel Tolkien you’d get Tolkien. But also only Beethoven from Ludwig van Beethoven.

1 Like

Thank you all,
The solution works for the sort, but not on the WHERE.

I was under the impression that this code was only for dataviewjs.

If you want it in the WHERE clause, or other parts you can use it in combination with FLATTEN like siren in this variant:

```dataview
Table WITHOUT ID 
  LastName,
  link(file.name, Titel) AS Titel,
  embed(link(cover, "150")) AS Cover, 
  choice(gekocht , "✅", "✘") as Gekocht,
  Schrijver
FROM "02 - Multimedia/02 - Boeken/Boeken"
FLATTEN slice(split(Schrijver, " "), -1) as LastName
WHERE (LastName[0] >= "A" and LastName[0] <="F")
	Sort LastName, Titel ASC
```
2 Likes

Thanks, it works.
I still don’t understand the concept of Flatten.

Some books have a tag ‘book’ or ‘epub’ or both.
But with a table you see a line for each tag, so I tried flatten (to have then on one line) but then I got two books in the view one with each tag.
This seems logical because it are two things but still.

I’ll try to get a better understanding of this.

If you use FLATTEN on a list, it’ll split the current row into multiple rows where each new row has the unique values of that list in addition to all other available information.

If you use FLATTEN on a single value, it can be used to compute a new intermediate value for user later on in the query or for display.

If you want to filter/map a list, and store the intermediate result for later use, you’ll need to do something like: FLATTEN list( ... ) as newList where you replace the ... with the expression doing something with a list which returns a list.

Does this clarify a little on the usage of FLATTEN?

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