4
violation[{"msg": msg}] {
    required:= ["red", "green", "blue"]
    input := ["orange", "purple"]

    msg := sprintf("")
}

I want to compare each value from the input array in the required array. In other languages, two normal loops will do it. but in the Rego language, they are no loops. Does anybody know how can I do it

Will Beason
  • 3,417
  • 2
  • 28
  • 46
Xameer
  • 105
  • 2
  • 11

3 Answers3

1

See the docs section on iteration for how to iterate over a collection. It is however often more idiomatic to work with sets. Following your example:

violation[{"msg": msg}] {
    required := {"red", "green", "blue"}
    input.colors := {"orange", "purple"}
    
    count(required - input.colors) != 0

    msg := sprintf("input.colors (%v) does not contain all required colors (%v), [input.colors, required]")
}

Devoops
  • 2,018
  • 8
  • 21
1

colorSet and requiredSet variable shows how to convert array to set.

Using == operator we can figure out if all colors are present or not

package play

default allColorPresent = false

allColorPresent  {
   colorSet := {x | x := input.colors[_]} 
   requiredSet := {x | x := input. required[_]}
   colorSet == requiredSet
}
Bush
  • 261
  • 1
  • 11
0

There are many ways to do it:

import future.keywords.in

violation[{"msg": msg}] {
    required:= ["red", "green", "blue"]
    input_colors := ["orange", "purple", "blue"]
    
    wrong_colors := [ color | color := input_colors[_]; not (color in cast_set(required)) ]
    count(wrong_colors) > 0
    msg := sprintf("(%v) not in required colors (%v)", [wrong_colors, required])
}
import future.keywords.in
import future.keywords.every

all_colors_present(input_colors, required_colours) {
    every color in input_colors {
        color in cast_set(required_colours)
    }
}

violation[{"msg": msg}] {
    required:= ["red", "green", "blue"]
    input_colors := ["r", "green", "blue"]
    
    not all_colors_present(input_colors, required)
    msg := "not all colors present!"
}