Thought I should add an example of how the second could be useful. From this JSON:
{
"rules":[
{
"name":"rule1",
"source":[
{"name":"SrcA","ipAddress":"10.10.0.1"},
{"name":"SrcB","ipAddress":"10.10.0.2"},
{"name":"SrcC","ipAddress":"10.10.0.3"}
],
"dest":[
{"name":"DstD","ipAddress":"10.0.10.1"},
{"name":"DstE","ipAddress":"10.0.10.2"},
{"name":"DstF","ipAddress":"10.0.10.3"}
],
"service":[
{"name":"ssh","port":22}
]
},{
"name":"rule2",
"source":[
{"name":"SrcW","ipAddress":"10.20.0.1"},
{"name":"SrcX","ipAddress":"10.20.0.2"}
],
"dest":[
{"name":"DstY","ipAddress":"1.1.1.1"},
{"name":"DstZ","ipAddress":"1.1.1.2"}
],
"service":[
{"name":"http","port":80},
{"name":"https","port":443}
]
}
]
}
I can break the rules down into individual source:destination:service combinations like so:
$ cat test.json | jq -c ".rules[]|{name:.name,source:.source[]|.,dest:.dest[]|.,service:.service[]|.}"
{"name":"rule1","source":{"name":"SrcA","ipAddress":"10.10.0.1"},"dest":{"name":"DstD","ipAddress":"10.0.10.1"},"service":{"name":"ssh","port":22}}
{"name":"rule1","source":{"name":"SrcA","ipAddress":"10.10.0.1"},"dest":{"name":"DstE","ipAddress":"10.0.10.2"},"service":{"name":"ssh","port":22}}
{"name":"rule1","source":{"name":"SrcA","ipAddress":"10.10.0.1"},"dest":{"name":"DstF","ipAddress":"10.0.10.3"},"service":{"name":"ssh","port":22}}
{"name":"rule1","source":{"name":"SrcB","ipAddress":"10.10.0.2"},"dest":{"name":"DstD","ipAddress":"10.0.10.1"},"service":{"name":"ssh","port":22}}
{"name":"rule1","source":{"name":"SrcB","ipAddress":"10.10.0.2"},"dest":{"name":"DstE","ipAddress":"10.0.10.2"},"service":{"name":"ssh","port":22}}
{"name":"rule1","source":{"name":"SrcB","ipAddress":"10.10.0.2"},"dest":{"name":"DstF","ipAddress":"10.0.10.3"},"service":{"name":"ssh","port":22}}
{"name":"rule1","source":{"name":"SrcC","ipAddress":"10.10.0.3"},"dest":{"name":"DstD","ipAddress":"10.0.10.1"},"service":{"name":"ssh","port":22}}
{"name":"rule1","source":{"name":"SrcC","ipAddress":"10.10.0.3"},"dest":{"name":"DstE","ipAddress":"10.0.10.2"},"service":{"name":"ssh","port":22}}
{"name":"rule1","source":{"name":"SrcC","ipAddress":"10.10.0.3"},"dest":{"name":"DstF","ipAddress":"10.0.10.3"},"service":{"name":"ssh","port":22}}
{"name":"rule2","source":{"name":"SrcW","ipAddress":"10.20.0.1"},"dest":{"name":"DstY","ipAddress":"1.1.1.1"},"service":{"name":"http","port":80}}
{"name":"rule2","source":{"name":"SrcW","ipAddress":"10.20.0.1"},"dest":{"name":"DstY","ipAddress":"1.1.1.1"},"service":{"name":"https","port":443}}
{"name":"rule2","source":{"name":"SrcW","ipAddress":"10.20.0.1"},"dest":{"name":"DstZ","ipAddress":"1.1.1.2"},"service":{"name":"http","port":80}}
{"name":"rule2","source":{"name":"SrcW","ipAddress":"10.20.0.1"},"dest":{"name":"DstZ","ipAddress":"1.1.1.2"},"service":{"name":"https","port":443}}
{"name":"rule2","source":{"name":"SrcX","ipAddress":"10.20.0.2"},"dest":{"name":"DstY","ipAddress":"1.1.1.1"},"service":{"name":"http","port":80}}
{"name":"rule2","source":{"name":"SrcX","ipAddress":"10.20.0.2"},"dest":{"name":"DstY","ipAddress":"1.1.1.1"},"service":{"name":"https","port":443}}
{"name":"rule2","source":{"name":"SrcX","ipAddress":"10.20.0.2"},"dest":{"name":"DstZ","ipAddress":"1.1.1.2"},"service":{"name":"http","port":80}}
{"name":"rule2","source":{"name":"SrcX","ipAddress":"10.20.0.2"},"dest":{"name":"DstZ","ipAddress":"1.1.1.2"},"service":{"name":"https","port":443}}
This form of rule is ripe for optimization (that is, finding an efficient way to build rules or groups to reduce or eliminate duplication). You can also apply graph theory to find out if there's some other SrcD which has very similar access, but is missing from rule1.