Element-wise difference between two arrays in dataview

What I’m trying to do

I use inline metadata such as start:: 09:30 and end:: 10:30 to keep track and log the time I spend for each task in my daily note. My notes look something like

  • (start:: 09:30) reading Cleveland and McGill 1984 (end:: 10:30)
  • (start:: 13:45) generate stimuli with altair (end:: 14:45)

This will give me an array if I query inline using this.start or this.end. I want to be able to calculate the element-wise difference between these two arrays, such that if I type in the following dataview command,

Table 
start, end, (end - start) as duration
where file = this.file

I will be able to get a table of the start time, end time, and duration I’ve spent on each task for each day. Ideally, I also want something like a summation across all task durations, but I am currently stuck at the first step of each trying to calculate the element-wise difference between two arrays.

Things I have tried

I’ve looked into the documentation file for dataview as well as searched on this forum and reddit for a while, but I think the solutions I’ve encountered all involve some kind of javascript forEach loop. Is it possible to perform element-wise differences between two arrays in dataview?

Not got Obsidian on this Mac to test, but does FLATTEN help?

```dataview
TABLE 
L.start,
L.end,
L.end-L.start
WHERE file.name = this.file.name
FLATTEN file.lists as L
```

This works… but a hack:

- (start:: 09h15m) reading Cleveland and McGill 1984 (end:: 10h33m)
- (start:: 12h45m) generate stimuli with altair (end:: 14h47m)

```dataview
TABLE WITHOUT ID
L.start AS Start,
L.end AS End,
L.end - L.start AS Duration
WHERE file.name = this.file.name
FLATTEN file.lists as L
```

EDIT: This date and timestamp also works:

- (start:: 2023-04-11T09:15) reading Cleveland and McGill 1984 (end:: 2023-04-11T10:33)
- (start:: 2023-04-11T12:15) generate stimuli with altair (end:: 2023-04-11T19:21)

```dataview
TABLE WITHOUT ID
L.start AS Start,
L.end AS End,
L.end - L.start AS Duration
WHERE file.name = this.file.name
FLATTEN file.lists as L
```

The common solution is to flatten the arrays, and then do the calculation on separate entities. Like suggested by @anon63144152 .

Another issues related to your code is that just the “HH:mm” isn’t considered a timestamp, so I’ve earlier suggested to add a “random” date part in front to make it into a proper date. Your query could then look like:

```dataview
TABLE WITHOUT ID item.start, item.end, duration
FLATTEN file.lists as item
FLATTEN (date("2023-01-01T" + item.end) -
         date("2023-01-01T" + item.start)) as duration
WHERE file.path = this.file.path
```

Back to your original question, it’s hard to traverse two arrays in parallell using dataview (especially in a DQL query). It can be done using indexes with some very convoluted code, but I wouldn’t recommend doing that. It’s a little easier in dataviewjs, but you’re still running the risk of the arrays shifting positions so that you’re suddenly have a misalignment of your data.

So in general, although it theoretically can be done, it’s better to use FLATTEN on the list and keep them gathered within that item scope.

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