【问题标题】:Sorting objects in Rego, based on multiple attributes基于多个属性在 Rego 中对对象进行排序
【发布时间】:2022-07-19 15:55:30
【问题描述】:

我正在尝试在 OPA Rego 中编写一些代码,以根据多个属性的值对对象集合进行排序。我从字典中的对象开始,如下所示,我想对里面的对象进行排序并返回它们的相对 ID。 所以有字典

dict = { 
    "1": {"name": "ccc", "foo": "4"},
    "2": {"name": "aaa", "foo": "1"},
    "3": {"name": "bbb", "foo": "6"},
    "4": {"name": "eee", "foo": "5"},
    "5": {"name": "eee", "foo": "2"},
    "6": {"name": "ddd", "foo": "3"} 
}

首先按 name 排序,然后按 foo 我希望返回 [ 2 3 1 6 5 4] 请注意,对于 id 4 和 5,对象具有相同的 name,因此顺序应由 foo

决定

我的第一次尝试是

_sorted = res{ 
    orderBy = ["name", "foo"]
    sorted1 = sort([ x | x := dict[_][orderBy[0]] ])
    res = [id | sorted1[_] == dict[id][orderBy[0]] ]
}

但是当存在具有相同名称的对象时,这种方法会出现问题,因此以下结果"_sorted": ["2","3","1","6",**"4","5","4","5"**]

第二次尝试改用集合,解决了重复问题

_sorted = res{ 
    orderBy = ["name", "foo"]
    sorted1 = { x | x := dict[_][orderBy[0]] }
    res = [id | sorted1[_] == dict[id][orderBy[0]] ]
}

但我不知道如何让它对 2 个属性进行排序 - 最后一次尝试

_sorted = res{ 
    orderBy = ["name", "foo"]
    sorted1 = { x | x := dict[_][orderBy[0]] }
    sorted2 = { x | x := dict[_][orderBy[1]] }
    res = [id | sorted1[_] == dict[id][orderBy[0]]; sorted2[_] == dict[sid][orderBy[1]] ]
}

非常感谢任何建议 :-) 谢谢!

【问题讨论】:

    标签: sorting opa rego


    【解决方案1】:

    我认为声明式排序的关键是计算每个元素的排名,然后相应地构建一个数组。

    我在这里举了你的例子:playground

    rank(x, k, coll) := count(smaller) {
      smaller := { y | some y in coll; y[k] <= x[k] }
    }
    
    sorted(k, coll) := { r: sorted_("foo", es) |
        some r in numbers.range(1, count(coll))
        es := { e | some e in coll; r == rank(e, k, coll) }
    }
    
    # same as sorted, without the inner sorted_ call
    sorted_(k, coll) := { r: es |
        some r in numbers.range(1, count(coll))
        es := { e | some e in coll; r == rank(e, k, coll) }
    }
    
    result := [ x | x := sorted("name", dict)[_][_][_] ]
    

    它在 orderBy 数组中不是通用的——namefoo 在那里被硬编码。

    我认为添加一个新的内置函数可能会很酷:sort_by(any&lt;array&lt;object&gt;, set&lt;object&gt;) -&gt; array&lt;object&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 2013-03-13
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 2022-01-24
      相关资源
      最近更新 更多