2016-02-29 138 views
2

我有一个看起来像这样的序列:({: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)。

回答

3

这应该做的变换你是后:

(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时,第二个参数是搜索关键字。

+0

我实际上确实希望它是一个关键字,因为(1结果)抛出一个异常,其中结果是调用变换的结果。除非有一种不同的方式从地图上查找使用长整型而不是关键字 – kmc059000

+0

你真的可以得到这样的数字吗? '(关键字'a)'按预期给出':a',但'(关键字'1)'返回'nil'。你应该能够使用任何不可变的值进行查找,所以一个数字与任何其他值都没有什么不同。 –

+1

我把它改成了''(zipmap(map(comp keyword str kw)in)))''''''这对我很有用。幸运的是我的数据总是有字符串,而不是数字。 – kmc059000