View Problem

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
ExpandDiskEdit
ruby
histogram = {}
list.each { |item| histogram[item] = (histogram[item] || 0) +1 }
DiskEdit
ruby 1.9
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}
DiskEdit
ruby
list.inject(Hash.new(0)) {|h, item| h[item] += 1; h}
ExpandDiskEdit
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));
}
}
ExpandDiskEdit
java org.apache.commons
LinkedMap histogram = new LinkedMap();

for (Object letter : list)
histogram.put(letter, !histogram.containsKey(letter) ? 1 : MapUtils.getIntValue(histogram, letter) + 1);
ExpandDiskEdit
perl
foreach(@list) {
$histogram{$_}++;
}
DiskEdit
perl
$histogram{$_}++ for @list;
ExpandDiskEdit
groovy
histogram = [:]
list.each { item ->
if (!histogram.containsKey(item)) histogram[item] = 0
histogram[item]++
}
ExpandDiskEdit
groovy
histogram = [:]
list.each { histogram[it] = (histogram[it] ?: 0) + 1 }
DiskEdit
groovy
def histogram = [:].withDefault{ 0 }
list.each { histogram[it] += 1 }
histogram
DiskEdit
groovy
list.inject([:].withDefault{ 0 }) { map, nr -> map[nr] += 1; map}
ExpandDiskEdit
scala
list foreach { (x) => histogram += x -> (histogram.getOrElse(x, 0) + 1) }
ExpandDiskEdit
scala
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))
ExpandDiskEdit
scala
val histEntries = for {
key <- data.removeDuplicates
count = data.count(_ == key)
} yield (key -> count)
val hist = Map(histEntries: _*)
DiskEdit
scala
value.foldLeft(Map[T, Int]()){
(m, c) => m.updated(c, m.getOrElse(c, 0) + 1)
}
ExpandDiskEdit
scala scala

list.groupBy(identity).mapValues(_.size)
DiskEdit
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
DiskEdit
python 2.7+, 3.1+
from collections import Counter
h = Counter("abacbb")
print(h)
ExpandDiskEdit
cpp C++/CLI .NET 2.0
for each(String^ entry in input) hash[entry] = hash->ContainsKey(entry)
? Convert::ToInt32(hash[entry]->ToString()) + 1 : 1;
ExpandDiskEdit
cpp C++/CLI .NET 2.0
for each(String^ entry in input) dict[entry] = dict->ContainsKey(entry) ? dict[entry] + 1 : 1;
ExpandDiskEdit
cpp C++0x/C++11
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;
ExpandDiskEdit
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)
ExpandDiskEdit
fsharp
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
ExpandDiskEdit
fsharp
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)
ExpandDiskEdit
fsharp 2.0
let histogram =
list
|> Seq.groupBy (fun a -> a)
|> Seq.map(fun (key, elements) -> key, Seq.length elements)
|> Map.ofSeq
ExpandDiskEdit
erlang
% Imperative Solution
Histogram = histogram(List),
ExpandDiskEdit
erlang
% Functional (1) Solution
Histogram = histogram(List),
DiskEdit
erlang Using dict for a map.
lists:foldl(fun(Elem, OldDict) ->
dict:update_counter(Elem, 1, OldDict)
end,
dict:new(),
[a,b,a,c,b,b])).
DiskEdit
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
DiskEdit
csharp .NET 3.5
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()
)
);
}
}
ExpandDiskEdit
csharp .Net 3.5/Mono 2.8
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));
ExpandDiskEdit
php
$list = array("a","b","a","c","b","b");
$map = array_count_values($list);
DiskEdit
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"]
DiskEdit
haskell
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
DiskEdit
haskell
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"]
DiskEdit
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))))))
DiskEdit
clojure
(->> [:a :b :a :c :b :b]
(group-by identity)
(reduce (fn [m e] (assoc m (first e) (count (second e)))) {}))
DiskEdit
clojure
(reduce conj {} (for [[x xs] (group-by identity "abacbb")] [x (count xs)]))
DiskEdit
clojure
(frequencies ["a","b","a","c","b","b"])
DiskEdit
clojure
(frequencies '[a b a c b b])
ExpandDiskEdit
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)
ExpandDiskEdit
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)

Submit a new solution for ruby, java, perl, groovy ...