Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: add elipsis matching for arrays #1812

Open
srenatus opened this issue Oct 2, 2019 · 5 comments
Open

Proposal: add elipsis matching for arrays #1812

srenatus opened this issue Oct 2, 2019 · 5 comments

Comments

@srenatus
Copy link
Contributor

srenatus commented Oct 2, 2019

When we want to match each of these paths,

path1 = ["root", "private"]
path2 = ["root", "private", "foo"]
path3 = ["root", "private", "foo", "bar"]
path4 = ["root", "public"]

and only care for them to start with ["root", "private"], it would me nice if we could say

input.path == ["root", "private", ...]

and had it match all of path1, path2, and path3.

Right now, we have to explicitly state

input.path[0] == "root"
input.path[1] == "private"

to make it match those three paths.

@srenatus srenatus changed the title Proposal: add elipsis matching for lists Proposal: add elipsis matching for arrays Oct 2, 2019
@srenatus
Copy link
Contributor Author

srenatus commented Jul 9, 2020

This can be helped with, a little, by a helper definition:

path_prefix := {q | q := array.slice(input.path, 0, j + 1); input.path[j]}

This lets then use

path_prefix[["root", "private"]]

where we'd have liked to match with ["root", "private", ...], and it also allows for variables in the array:

> path_prefix := {q | q := array.slice(input.path, 0, j + 1); input.path[j]}
Rule 'path_prefix' defined in package repl. Type 'show' to see rules.
> path_prefix with input.path as ["foo", "bar", "baz"]
[
  [
    "foo"
  ],
  [
    "foo",
    "bar"
  ],
  [
    "foo",
    "bar",
    "baz"
  ]
]
> path_prefix[[x, "bar", y]] with input.path as ["foo", "bar", "baz"]
+-------+-------+--------------------------------+
|   x   |   y   |   path_prefix[[x, "bar", y]]   |
|       |       |   with input.path as ["foo",   |
|       |       |         "bar", "baz"]          |
+-------+-------+--------------------------------+
| "foo" | "baz" | ["foo","bar","baz"]            |
+-------+-------+--------------------------------+
>

@anderseknert
Copy link
Member

While I like this, is there something this provides more than what is shown in the example here?
It feels like this would just as well be improved by a a more succint way of expressing array slices, like e.g. Python provides:

input.path == ["root", "private", ...]

could be:

input.path[:2] == ["root", "private"]

Having a more powerful way of expressing array slices would have quite a few more benefits, like slicing from the end of the array, providing a custom step value, etc.

@anderseknert
Copy link
Member

Discussing this with @srenatus, it would be pretty neat if an elipsis operator would encompass objects as well, so you could do object destructuring like:

some {"name": name, "permissions": permissions, ...} in input.user.attributes

And perhaps it could be used to match parts of an object as well:

{"a: 1, "b": 2, ...} == {"a": 1, "b": 2, "c": 3}

@anderseknert
Copy link
Member

@johanfylling had an interesting case for this, where he wanted to do pattern matching for "last in path" without knowing the length of the array, e.g. something like

walk(object, [[..., "modules"], value])

@tsandall
Copy link
Member

I could also see the elipsis operator being useful for referencing documents at arbitrarily deep paths for dynamic composition... for example:

data.acme[path...].allow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Nice To Have
Development

No branches or pull requests

3 participants