Thanks for the confidence…
I’ve already alluded to the solution, I think, in a previous post, and I hope the following might do the trick:
```dataview
LIST
FROM #setting
FLATTEN
choice(typeof(this.proj) = "string",
list(this.proj), this.proj) as projList
WHERE file.path != this.file.path
WHERE any(map(projList, (p) => contains(proj, p)))
SORT file.name ASC
```
There are two key variations in this script compared to the original script:
- Ensure
this.proj
is always a list, e.g. projList
- Check
proj
against all values in projList
Ensure this.proj
is always a list
Since this.proj
can be a single-value or a multi-value field, it’ll cause issues if we don’t do some trickery. I found that it’s best to just ensure it’s always a list, and handle the multi-value case as the default case. This part of the query handles this:
FLATTEN
choice(typeof(this.proj) = "string",
list(this.proj), this.proj) as projList
This checks to see if this.proj
is a string, aka a single value, and if so it does the list(this.proj)
which makes a list with just that one value. If it’s already a list, then just keep using this. Store the result of this into projList
.
Do note that you to trigger an array creation in an inline field you’ll need to use quotes. Try the following in a note to see the differences:
[projA:: Portal]
[projB:: Portal, Rom]
[projC:: "Portal", "Rom"]
[projD:: Portal]
[projD:: Rom]
typeof projA --> `= typeof(this.projA) `
typeof projB --> `= typeof(this.projB) `
typeof projC --> `= typeof(this.projC) `
typeof projD --> `= typeof(this.projD) `
This should report “string”, “string”, “array” and “array”
See how only the latter one is reported as an array (or list) of multiple values. projB
is just one value of “Portal, Rom”, not the two separate values. So either you’ll need to use quotes around multiple values (aka projC
), or you need to add them in different defintions (aka projD
).
Check proj
against all values in projList
When we’ve ensured that projList
is the list of the various projects we want to check against, we need to do the double loop. If I understood you correctly you wanted to list all notes matching any of the projects, so that lead to this query part:
WHERE any(map(projList, (p) => contains(proj, p)))
Lets try to explain it (again):
-
any( ... )
– Include the file if any of the arguments is true. Other variations could be all()
or none()
-
map(projList, (p) => ... )
– Loop through all of the elements of projList
, and for each of them use that element as m
in the expression which follows. Keep track of the result of all these expression, and pass it onto the method above
-
contains(proj, p)
– Use the “familiar” expression to check for the single value. That is check that proj
contains the single value of p
. If found return true
, and if not found return false
.
Hopefully, that explains the added logic, and gives you the result you wanted. Query is untested, as I don’t have files setup like you have sketched for us. One caveat could be if proj
in the various notes have multiple values, but I think it should work in that case too. And as stated above, you do need to make sure that this.proj
is an actual list, aka have quotes around the various values, for the query to work.