使用每个映射中的键的值将映射序列转换为映射映射
问题描述:
我有一个看起来像这样的序列:({:a 1 :b "lorem"} {:a 2 :b "ipsum"})
,我想将其转换为使用值:a
作为值的映射映射新地图中的关键字。我期待的结果是{:1 {:a 1 :b "lorem"} :2 {:a 2 :b "ipsum"}}
。使用每个映射中的键的值将映射序列转换为映射映射
也许这不是惯用的clojure,我还在学习。我基本上会收到一个很大的序列,并且我将在每个映射中以这个序列中的某个值查找值,并且我想使用映射使其成为O(1)。
在C#中,在IEnumerable
上,可以调用.ToDictionary(x => x.SomeProperty)
,它将返回键值对字典,使用值SomeProperty
作为键。对于列表/序列,这具有O(1)的查找性能,而不是典型的O(N)。
答
这应该做的变换你是后:
(def latin '({:a 1 :b "lorem"} {:a 2 :b "ipsum"}))
(defn transform [kw in]
(zipmap (map kw in) in))
=> (transform :a latin)
{1 {:a 1, :b "lorem"}, 2 {:a 2, :b "ipsum"}}
我换号的关键字犹豫了,因为不知道为你想这样做的原因......
...... 编辑 - 因为你总是可以做一个索引(O(1))来检索像这样:
(get (transform :a latin) 1)
1
不因为它不能用作函数(不像:1
),但get
是一个函数,当第一个参数是map时,第二个参数是搜索关键字。
我实际上确实希望它是一个关键字,因为(1结果)抛出一个异常,其中结果是调用变换的结果。除非有一种不同的方式从地图上查找使用长整型而不是关键字 – kmc059000
你真的可以得到这样的数字吗? '(关键字'a)'按预期给出':a',但'(关键字'1)'返回'nil'。你应该能够使用任何不可变的值进行查找,所以一个数字与任何其他值都没有什么不同。 –
我把它改成了''(zipmap(map(comp keyword str kw)in)))''''''这对我很有用。幸运的是我的数据总是有字符串,而不是数字。 – kmc059000