View Subcategory

Create a histogram map from a list

Given the list [a,b,a,c,b,b], produce a map {a:2, b:3, c:1} which contains the count of each unique item in the list
python
from collections import defaultdict
h = defaultdict(int)
for k in "abacbb":
h[k] += 1

h = {}
for k in "abacbb":
h[k] = h.setdefault(k, 0) + 1
from collections import Counter
h = Counter("abacbb")
print(h)
csharp
using System.Collections.Generic;
using System.Linq;

// This is a "functional" C# approach

// NOTE: In C# "maps" are of type Dictionary<Tkey, TValue>
// so our histogram map is of type Dictionary<object, int>
public class HistogramMap {
public Dictionary<object, int> FromList(List<object> list) {
// The "Aggregate" method works like "inject" in many other languages.
return list.Aggregate(
new Dictionary<object, int>(),
(map, obj) => {
// If this is the first time we've seen this obj, set the count to 0
if (!map.ContainsKey(obj)) map[obj] = 0;

// Increment the count
map[obj]++;

// Return the map for the next iteration.
// NOTE: This does NOT return from our "FromList" method
return map;
}
);
}

public static void Main() {
// Create our Histogram Map from a new list
var map = new HistogramMap().FromList(
new List<object>() { 'a', 'b', 'a', 'c', 'b', 'b' }
);

// This just prints the result
System.Console.WriteLine (
string.Join (", ",
// "Select" works like "map" or "collect" in many other languages
map.Select( kvp =>
string.Format("{0} : {1}", kvp.Key, kvp.Value)
).ToArray()
)
);
}
}
new[] {"a","b","a","c","b","b"}
.GroupBy(s => s)
.Select(s => new { Value = s.Key, Count = s.Count() })
.ToList()
.ForEach(e => Console.WriteLine("{0} : {1} ", e.Value, e.Count));
erlang
% Imperative Solution
Histogram = histogram(List),
% Functional (1) Solution
Histogram = histogram(List),
lists:foldl(fun(Elem, OldDict) ->
dict:update_counter(Elem, 1, OldDict)
end,
dict:new(),
[a,b,a,c,b,b])).
fsharp
let histogram = (List.foldLeft (fun (acc : Map<char, int>) (e : char) -> if (Map.mem e acc) then (Map.add e ((Map.find e acc) + 1) acc) ; else (Map.add e 1 acc)) (Map.empty) list)
let histogram list =
let rec histogram' list' dict' =
match list' with
| [] -> dict'
| x :: xs ->
match Map.tryFind x dict' with
| Some(Value) -> histogram' xs (Map.add x (Value + 1) dict')
| None -> histogram' xs (Map.add x 1 dict')
histogram' list Map.empty

// ------

let histogram' = histogram list
let histogram = (List.foldLeft (fun (acc : Generic.Dictionary<char, int>) (e : char) -> (if acc.ContainsKey(e) then acc.[e] <- acc.[e] + 1 ; else acc.Add(e, 1)) ; acc) (new Generic.Dictionary<char, int>()) list)
let histogram =
list
|> Seq.groupBy (fun a -> a)
|> Seq.map(fun (key, elements) -> key, Seq.length elements)
|> Map.ofSeq

Categorise a list

Given the list [one, two, three, four, five] produce a map {3:[one, two], 4:[four, five], 5:[three]} which sorts elements into map entries based on their length
python
c = defaultdict(list)
for k in ["one", "two", "four", "three", "five"]:
c[len(k)].append(k)
from itertools import groupby
lst = ["one", "two", "four", "three", "five"]
c = dict((k, list(g)) for k,g in
groupby(sorted(lst, key=lambda x: len(x)), key=lambda x: len(x)))
print(c)
csharp
using System.Collections.Generic;
using System.Linq;
public class ListCategorizer {
public static void Main() {
var list = new List<string>() { "one", "two", "three", "four", "five" };
var categories = list.GroupBy(el => el.Length)
.ToDictionary( g => g.Key, // key
g => g.ToList() ); // value
}
}
erlang
% Imperative Solution
CatList = categorise(List),
% Functional (1) Solution
CatList = categorise(List),
fsharp
let catmap = (List.foldLeft (fun (acc : Map<int, List<string> >) (e : string) -> if (Map.mem e.Length acc) then (Map.add e.Length ((Map.find e.Length acc) @ [e]) acc) ; else (Map.add e.Length [e] acc)) (Map.empty) list)
let lengthMap =
["one"; "two"; "three"; "four"; "five"]
|> Seq.groupBy (fun s -> s.Length)
|> Seq.map (fun (length, entries) -> (length, entries |> List.ofSeq))
|> Map.ofSeq