的一種方法是先寫一個函數,它接受一個有序對如(2,"c")
和有序對諸如
[(3,["a"]),(2,["b"]),(1,["a","e"])]
的列表,並返回與上漲到適當的列表中的元素的修改列表(或創建如果不存在新的(鍵,列表)對),這樣的結果會是這樣的:
[(3,["a"]),(2,["c","b"]),(1,["a","e"])]
以下功能的伎倆:
fun store ((k,v), []) = [(k,[v])]
| store ((k,v), (m,vs)::items) = if k = m
then (m,v::vs)::items
else (m,vs)::store ((k,v) ,items);
鑑於鍵列表和值的對應列表,你可以在鍵和值的相應拉鍊最後這個功能摺疊:
fun group ks vs = foldl store [] (ListPair.zip(ks,vs));
例如,如果
val original = [1, 2, 0, 1, 1, 2];
val elements = ["a","b","c","d","e","f"];
- group original elements;
val it = [(1,["e","d","a"]),(2,["f","b"]),(0,["c"])] : (int * string list) list
請注意,如果需要,您可以根據鍵對列表進行排序。
最後 - 如果你只是想組(逆轉到列表中的原來的順序一致)以下工作:
fun groups ks vs = map rev (#2 (ListPair.unzip (group ks vs)));
例如,
- groups original elements;
val it = [["a","d","e"],["b","f"],["c"]] : string list list
上編輯:如果你想根據關鍵字(而不是它們出現的順序)對最終答案進行排序,你可以使用@SimonShine的想法並按照排序順序存儲數據,或者你可以對group
函數的輸出進行排序。有點奇怪的是,SML Standard Basis Library lacks a built-in sort,但是標準實現有它們自己的分類(並且很容易編寫你自己的)。例如,使用SML/NJ的排序,你可以這樣寫:
fun sortedGroups ks vs =
let
val g = group ks vs
val s = ListMergeSort.sort (fn ((i,_),(j,_)) => i>j) g
in
map rev (#2 (ListPair.unzip s))
end;
領先於預期:
- sortedGroups original elements;
val it = [["c"],["a","d","e"],["b","f"]] : string list list
預期什麼不起作用? – ceving
創建智能方法的過程。 – brumbrum
這看起來很像[分區到等價類的列表](http://stackoverflow.com/questions/40577169/partition-a-list-into-equivalence-classes)10天前回答。通過一個僅考慮數字的等價函數調用兩個列表和組對上的ListPair.zip。你也可以從Haskell的['group'](https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-List.html#v:group)/ ['groupBy']( https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-List.html#v:groupBy),儘管源代碼可能有點難以閱讀。 –