Home > Back-end >  REGO how to get object (map) keys that match a pattern
REGO how to get object (map) keys that match a pattern

Time:01-15

Working with Rego, the Open Policy Agent (OPA) "rules" language, and given the following data:

{
    "x-foo": "a",
    "x-bar": "b",
    "y-foo": "c",
    "y-bar": "d"
}

what is the correct Rego expression(s) or statement(s) to get just the keys that start with "x-"? That is, I want an array of

[ "x-foo", "x-bar" ]

I know about the startswith() function, and I've tried various attempts at comprehensions, but no matter what I try I can't get it to work.

Any help would be much appreciated.

CodePudding user response:

Comprehension format

mm = {
    "x-foo": "a",
    "x-bar": "b",
    "y-foo": "c",
    "y-bar": "d"
    }
x_keys = [key for key in mm.keys() if key.startswith('x')]
print(x_keys)

OR

mm = {
    "x-foo": "a",
    "x-bar": "b",
    "y-foo": "c",
    "y-bar": "d"
    }

for i in mm.keys():
    if i.startswith('x'):
        print(i)

I hope you find this useful.

CodePudding user response:

This can be accomplished either by using a comprehension, like you suggest, or a partial rule that generates a set:

x_foo_comprehension := [key | object[key]; startswith(key, "x-")]

x_foo_rule[key] {
    object[key]
    startswith(key, "x-")
}

Finally, if you need to take nested keys into account, you could use the walk built-in to traverse the object:

x_foo_rule[key] {
    walk(object, [path, value])
    last := path[count(path) - 1]
    startswith(last, "x-")
    key := concat(".", path)
}

# x_foo_rule == {
#     "x-bar",
#     "x-foo",
#     "y-bar.x-bar",
#     "y-bar.x-foo"
# ]
  •  Tags:  
  • Related