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
ruby
histogram = {}
list.each { |item| histogram[item] = (histogram[item] || 0) +1 }
list = %w{a b a c b b}

histogram = list.each_with_object(Hash.new(0)) do |item, hash|
hash[item] += 1
end

p histogram # => {"a"=>2, "b"=>3, "c"=>1}
list.inject(Hash.new(0)) {|h, item| h[item] += 1; h}
java
Map map = new HashMap();
for (Iterator it = list.iterator(); it.hasNext();) {
String s = (String) it.next();
if (!map.containsKey(s)) {
map.put(s, new Integer(1));
} else {
map.put(s, new Integer(((Integer)map.get(s)).intValue() + 1));
}
}
LinkedMap histogram = new LinkedMap();

for (Object letter : list)
histogram.put(letter, !histogram.containsKey(letter) ? 1 : MapUtils.getIntValue(histogram, letter) + 1);
perl
foreach(@list) {
$histogram{$_}++;
}
$histogram{$_}++ for @list;
groovy
histogram = [:]
list.each { item ->
if (!histogram.containsKey(item)) histogram[item] = 0
histogram[item]++
}
histogram = [:]
list.each { histogram[it] = (histogram[it] ?: 0) + 1 }
def histogram = [:].withDefault{ 0 }
list.each { histogram[it] += 1 }
histogram
list.inject([:].withDefault{ 0 }) { map, nr -> map[nr] += 1; map}
scala
list foreach { (x) => histogram += x -> (histogram.getOrElse(x, 0) + 1) }
val data = List("a", "b", "a", "c", "b", "b")
val keys = data removeDuplicates
val hist = Map.empty[String, Int] ++ keys.map{ k => (k, (data count (_==k)))}
assert(hist == Map("a"->2, "b"->3, "c"->1))
val histEntries = for {
key <- data.removeDuplicates
count = data.count(_ == key)
} yield (key -> count)
val hist = Map(histEntries: _*)
value.foldLeft(Map[T, Int]()){
(m, c) => m.updated(c, m.getOrElse(c, 0) + 1)
}

list.groupBy(identity).mapValues(_.size)
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)
cpp
for each(String^ entry in input) hash[entry] = hash->ContainsKey(entry)
? Convert::ToInt32(hash[entry]->ToString()) + 1 : 1;
for each(String^ entry in input) dict[entry] = dict->ContainsKey(entry) ? dict[entry] + 1 : 1;
map<string,int> hist;
for (auto e: { "a","b","a","c","b","b" })
++hist[e];
for (auto e: hist)
cout << e.first << " : " << e.second << endl;
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
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])).
ocaml
module StringMap = Map.Make (String)

let histogram lst =
List.fold_left (fun m v ->
let n =
if StringMap.mem v m
then succ (StringMap.find v m)
else 1
in
StringMap.add v n m
) StringMap.empty lst

let () =
let h = histogram ["a"; "b"; "a"; "c"; "b"; "b"] in
StringMap.iter (fun key value ->
Printf.printf " %s: %d\n" key value
) 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));
php
$list = array("a","b","a","c","b","b");
$map = array_count_values($list);
haskell
import Data.List
import qualified Data.Map as Map

histogram :: Ord a => [a] -> Map.Map a Int
histogram xs = Map.fromList [ (head l, length l) | l <- group (sort xs) ]

output :: Map.Map String Int
output = histogram ["a","b","a","c","b","b"]
import Control.Arrow
import Data.List
import qualified Data.Map as Map
import System.Random

histogram :: Ord a => [a] -> Map.Map a Int
histogram = Map.fromList . map (head &&& length) . group . sort

main = print . histogram . take 1000 . randomRs (1::Int, 100) =<< newStdGen
import qualified Data.Map as Map

histogram :: [String] -> Map.Map String Int
histogram ss = foldl addElem Map.empty ss
where addElem m e = Map.insertWith (+) e 1 m

output :: Map.Map String Int
output = histogram ["a","b","a","c","b","b"]
clojure
(let [l '[a b a c b b]]
(loop [m {}
d (distinct l)]
(let [item (first d)]
(if (zero? (count d))
m
(recur
(assoc m
item
(count
(filter #(= item %) l)))
(rest d))))))
(->> [:a :b :a :c :b :b]
(group-by identity)
(reduce (fn [m e] (assoc m (first e) (count (second e)))) {}))
(reduce conj {} (for [[x xs] (group-by identity "abacbb")] [x (count xs)]))
(frequencies ["a","b","a","c","b","b"])
(frequencies '[a b a c b b])
fantom
list := ["a","b","a","c","b","b"]
map := [Str:Int][:]
list.each |Str s, Int i| { if(!map.containsKey(s)) map.add(s,1); else map[s] = ++map[s] }
echo (map)
go
var maplist = make(map[string]int)
var list = [6]string{"a","b","a","c","b","b"}
for _, v := range list {
maplist[v] += 1
}
fmt.Println(maplist)

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
ruby
lengths = {}
list.each do |x|
len = x.size
lengths[len] = (lengths[len] || [])
lengths[len] << x
end
lengths = list.group_by {|x| x.size}
list.inject({}) { |h,x| (h[x.size]||=[]) << x; h }
java
SortedMap<Integer, List<String> > map = new TreeMap<Integer, List<String> >(); int key; List<String> vlist;

for (String item : list)
{
key = item.length(); vlist = map.containsKey(key) ? map.get(key) : new ArrayList<String>();
vlist.add(item); map.put(key, vlist);
}
MultiValueMap map = new MultiValueMap();
for (Object item : list) map.put(((String) item).length(), item);
perl
@list = qw(one two three four five);
push @{$map{length($_)}}, $_ for (@list);
groovy
map = ['one', 'two', 'three', 'four', 'five'].groupBy{ it.size() }
scala
list foreach { (x) => map += x.length -> (x :: map.getOrElse(x.length, Nil)) }
list foreach { (x) => map += x.length -> (map.getOrElse(x.length, Nil) ::: List(x)) }
List("one", "two", "three", "four", "five") groupBy (_ size)
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)
cpp
for each(String^ entry in input)
{
key = entry->Length;
if (!hash->ContainsKey(key)) hash[key] = gcnew ArrayList;
safe_cast<ArrayList^>(hash[key])->Add(entry);
}
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
erlang
% Imperative Solution
CatList = categorise(List),
% Functional (1) Solution
CatList = categorise(List),
ocaml
let map =
List.fold_left (fun map v ->
let len = String.length v in
let before =
try IntMap.find len map
with Not_found -> [] in
IntMap.add len (v :: before) map
) IntMap.empty ["one"; "two"; "three"; "four"; "five"]
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
}
}
php
foreach ($array as $m) {
$l = strlen($m);
$map[$l][] = $m;
}
arsort($map);
haskell
import qualified Data.Map as Map

groupInMapBy :: Ord k => (a -> k) -> [a] -> Map.Map k [a]
groupInMapBy f = foldr (\a -> Map.insertWith (++) (f a) [a]) Map.empty

output :: Map.Map Int [String]
output = groupInMapBy length ["one", "two", "three", "four", "five"]
import Data.List (groupBy, sortBy)
import Data.Function (on)

groupInPairsBy :: Ord k => (a -> k) -> [a] -> [(k, [a])]
groupInPairsBy f = map (\xs -> (f (head xs), xs)) .
groupBy ((==) `on` f) . sortBy (compare `on` f)

output :: [(Int, [String])]
output = groupInPairsBy length ["one", "two", "three", "four", "five"]
clojure
(loop [m {}
l ["one" "two" "three" "four" "five"]]
(if (zero? (count l))
m
(let [item (first l)
key (count item)]
(recur
(assoc m key (cons item (get m key [])))
(rest l)))))
(group-by count ["one" "two" "three" "four" "five"])
fantom
list := ["one", "two", "three", "four", "five"]
map := [Int:List][:]
list.each { List l := map[it.size] ?: [,]; map[it.size] = l.add(it) }
echo(map)