3

次のような地図があります。

user> (frequencies "aaabccddddee")
{\a 3, \b 1, \c 2, \d 4, \e 2}

そして、引数として渡す文字列に各文字が出現する順序に従って、キーと値のペアを並べ替える関数が必要です。

このようなもの:

user> (somesort "defgcab" (frequencies "aaabccddddee"))
[[\d 4] [\e 2] [\c 2] [\a 3] [\b 1]]

(上記の例では、'f' と 'g' はマップに表示されないため、無視されます。文字列 (この例では "defgcab") には、マップ内のすべての文字/キーが含まれていることが保証されています。 )

結果として得られるコレクションは、ソートされている限り、それほど重要ではありません。

私はいくつかのことを試しましたが、これを機能させる方法が見つかりません。

4

4 に答える 4

6

並べ替えロジックを実行するために使用することを好みsort-by、コレクション用のカスタム コンパレータを作成するだけです。

(defn sorter [coll] (zipmap coll (range)))

(sort-by (comp (sorter "defgcab") key) 
         (frequencies "aaabccddddee"))

;=> ([\d 4] [\e 2] [\c 2] [\a 3] [\b 1])

編集:これには、必要に応じてコレクションをマップに保持できるというさらなる利点がありますが、もう少し作業を行う必要があります。

(defn map-sorter [coll]
  (let [order (zipmap coll (range))]
    (fn [a b]
      (compare (order a) (order b)))))

(into (sorted-map-by (map-sorter "defgcab"))
      (frequencies "aaabccddddee"))

;=> {\d 4, \e 2, \c 2, \a 3, \b 1}
于 2012-05-17T02:12:00.570 に答える
2

で表現された Ankur のソリューションはfor、おそらく少し読みやすいです。

(defn somesort [str st] 
    (for [c str :let [v  (get st c)] :when v] [c v]))

これは、カスタムの並べ替え文字列の文字が一意であると想定して機能します。

ソート文字列は 1 回繰り返され、その各文字がマップで検索されます。関数に渡されたマップがハッシュ マップであることを確認すると、これは線形になります。

于 2012-05-16T13:27:04.340 に答える
2
(defn somesort [str st] 
    (filter (fn [[k v]] v ) (map (fn [c] [c (get st c)]) str)) )

仕組み:

  • その文字列の各文字の「ソート文字列」でマップを使用して、対応するキー値をセットからベクトルとして取得します
  • フィルターを使用して、値が nil である要素を除外します
于 2012-05-16T12:04:16.517 に答える