View Subcategory

Join the elements of a list, separated by commas

Given the list [Apple, Banana, Carrot] produce "Apple, Banana, Carrot"
ruby
string = fruit.join(', ')
java
StringBuffer sb = new StringBuffer();
for (Iterator it = fruit.iterator(); it.hasNext();) {
sb.append(it.next());
if (it.hasNext()) {
sb.append(", ");
}
}
String result = sb.toString();
StringBuilder sb = new StringBuilder(fruit.get(0));
for (String item : fruit.subList(1, fruit.size())) sb.append(", ").append(item);
String result = sb.toString();
String result = StringUtils.join(fruit, ", ");
perl
print join ', ', qw(Apple Banana Carrot);
# Longer and less efficient than join(), but illustrates
# Perl's foreach operator, which can be useful for
# less trivial problems with lists

@list = ('Apple', 'Banana', 'Carrot');
foreach $fruit (@list) {
print "$fruit,";
}
print "\n";
my @a = qw/Apple Banana Carrot/;
{
local $, = ", ";
print @a
}
print "\n";
my @a = qw/Apple Banana Carrot/;
{
local $" = ", ";
print "@a\n";
}
groovy
string = fruit.join(', ')
string = fruit.toString()[1..-2]
scala
val result =
((fruit.tail foldLeft (new StringBuilder(fruit.head))) {(acc, e) => acc.append(", ").append(e)}).toString
val result = fruit.mkString(",")
val fruit = List[String]("Apple", "Banana", "Carrot")
println(fruit.mkString(", "))
python
print ", ".join(['Apple', 'Banana', 'Carrot'])
cpp
String^ result = String::Join(L", ", fruit->ToArray());
string fruits[] = {"Apple", "Banana", "Carrot"};
string result = boost::algorithm::join(fruits, ", ");
fsharp
let result = String.Join(", ", [|"Apple"; "Banana"; "Carrot"|])
let result = (List.fold_left (fun acc item -> acc ^ (", " ^ item)) (List.hd fruit) (List.tl fruit))
let result = (List.fold_left (fun (acc : StringBuilder) (item : string) -> acc.Append(", ").Append(item)) (new StringBuilder(List.hd fruit)) (List.tl fruit)).ToString()
erlang
Result = string:join(Fruit, ", "),
Result = lists:foldl(fun (E, Acc) -> Acc ++ ", " ++ E end, hd(Fruit), tl(Fruit)),
Result = lists:flatten([ hd(Fruit) | [ ", " ++ X || X <- tl(Fruit)]]).
ocaml
let () =
let lst = ["Apple"; "Banana"; "Carrot"] in
let str = String.concat ", " lst in
print_endline str
csharp
using System.Collections.Generic;
public class JoinEach {
public static void Main() {
var list = new List<string>() {"Apple", "Banana", "Carrot"};
System.Console.WriteLine( string.Join(", ", list.ToArray()) );
}
}
php
$string = implode(", ", $fruits);
haskell
import Data.List

let join = intercalate ", " ["Apple", "Banana", "Carrot"]
clojure
(apply str (interpose ", " '("Apple" "Banana" "Carrot")))
fantom
["Apple", "Banana", "Carrot"].join(", ")
go
s := strings.Join([]string {"Apple", "Banana", "Carrot"}, ", ")

Join the elements of a list, in correct english

Create a function join that takes a List and produces a string containing an english language concatenation of the list. It should work with the following examples:
join([Apple, Banana, Carrot]) = "Apple, Banana, and Carrot"
join([One, Two]) = "One and Two"
join([Lonely]) = "Lonely"
join([]) = ""
ruby
def join(arr)
return '' if not arr
case arr.size
when 0 then ''
when 1 then arr[0]
when 2 then arr.join(' and ')
else arr[0..-2].join(', ') + ', and ' + arr[-1]
end
end
java
private String join(List elements) {
if (elements == null || elements.size() == 0) {
return "";
} else if (elements.size() == 1) {
return elements.get(0).toString();
} else if (elements.size() == 2) {
return elements.get(0) + " and " + elements.get(1);
}
StringBuffer sb = new StringBuffer();
for (Iterator it = elements.iterator(); it.hasNext();) {
String next = (String) it.next();
if (sb.length() > 0) {
if (it.hasNext()) {
sb.append(", ");
} else {
sb.append(", and ");
}
}
sb.append(next);
}
return sb.toString();
}
System.out.println(join(fruit));
perl
sub myjoin {
$_ = join ', ', @_;
s/, ([^,]+)$/ and $1/;
return $_;
}


# Note: I don't think this meets the spec --Geoff
sub myjoin {
if ($#_ < 2) {
return join ' and ', @_;
} else {
return join(', ', @_[0..$#_-1]) . ' and ' . $_[-1];
}
}

# Note: I don't think this meets the spec --Geoff
# Previous "myjoin()" responses don't meet the spec of including
# the final comma before the "and" if the list has more than
# two elements...this is one way to meet that spec...it may
# not be the most efficient...

sub AnotherMyJoin {
my @list = @_;

if ($#list == -1) {return}
elsif ($#list == 0) {return $list[0]}
elsif ($#list == 1) {return $list[0].' and '.$list[1]}
else {
return join(", ", @list[0..$#list - 1]) . ', and '. $list[$#list];
}
}
# This is the long way, but it's kind of fun
# It illustrates the use of Perl's reverse()
# operator to work our way through the list
# elements backwards...I wrote this one before
# getting smart and looking at some of the other
# algorithms from the other languages. Still,
# it is only 12 lines of code vs 9 for my other
# solution if you disregard the comments.

sub myjoin {
my @list = reverse(@_); # Reverse original order of elements
my $retval;

# Make our exit here if we were passed an empty list
if ($#list == -1) {return}

# Loop through reversed elements in end-to-start order
for (0..$#list) {
# Add the reversed form of each element plus a space char
$retval .= reverse($list[$_]).' ';

# Add 'and' to lists with two or more elements
# placing it in between final and 'next to final'
$retval .= "dna " if ($#list > 0 and $_== 0);

# Add ',' to each element as long as there are more
# than two elements and the current element isn't the
# final element
$retval .= "," if ($#list > 1 and $_ != $#list);
}

# Remove what will end up as an extraneous leading space
chop($retval);

# Done looping, now reverse things back into correct order and return
$retval = reverse($retval);
return($retval);
}
# Yes, this doesn't meet the spec, the spec is flawed
# the serial comma (Oxford comma) is not required in a list
sub english_join {
return join(', ', @_[0..$#_-1])
. ($#_ ? ' and ' : '' )
. $_[-1];
}
groovy
def join(list) {
if (!list) return ''
switch(list.size()) {
case 1:
return list[0]
case 2:
return list.join(' and ')
default:
return list[0..-2].join(', ') + ', and ' + list[-1]
}
}
ArrayList.metaClass.joinEng = { ->
def closureMap = [0: { -> delegate.join(' and ')}, 1 : {-> delegate.join(' and ')}].withDefault { k -> { -> delegate[0..-2].join(', ') + ', and ' + delegate[-1] } }
if (delegate.size()) closureMap[delegate.size()-1].call()
else ""
}

assert ["a"].joinEng() == "a"
assert ["a", "b"].joinEng() == "a and b"
assert ["a", "b", "c"].joinEng() == "a, b, and c"
assert [].joinEng() == ""
def join(list) {
list.join(', ').reverse().replaceFirst(/,/, "dna ").reverse()
}
scala
def join(list : List[String]) : String = list match {
case List() => ""
case List(x) => x
case List(x,y) => x + " and " + y
case List(x,y,z) => x + ", " + y + ", and " + z
case _ => list(0) + ", " + join(list.tail)
}
def join(list : List[String]) : String = list match {
case List() => ""
case List(x) => x
case List(x,y) => x + " and " + y
case List(x,y,z) => x + ", " + y + ", and " + z
case x::xs => x + ", " + join(xs)
}
def join[T](list : List[T]) = list match {
case xs if xs.size < 3 => xs.mkString(" and ")
case xs => xs.init.mkString(", ") + ", and " + xs.last
}
python
def join(*x):
if len(x) <= 2:
return ' and '.join(x)
else:
return ', '.join(x[:-1] + ('and ' + x[-1],))

if __name__ == "__main__":
assert join("Apple", "Banana", "Carrot") == "Apple, Banana, and Carrot"
assert join("One", "Two") == "One and Two"
assert join("Lonely") == "Lonely"
assert join(*[]) == ""
cpp
Console::WriteLine(join(fruit));
string join(const vector<string> &s, int b=0)
{
switch (s.size() - b)
{
case 0: return "";
case 1: return s[b];
case 2: return s[b] + (s.size() > 2 ? "," : "") + " and " + s[b+1];
default: return s[b] + ", " + join(s, b+1);
}
}
fsharp
let join list =
let rec join' list' s =
match list' with
| [] -> s
| [w] -> join' [] (s ^ " and " ^ w)
| w :: ws -> join' ws (s ^ ", " ^ w)
match list with
| [] -> ""
| w :: ws -> join' ws w

// ------

printfn "%s" (join fruit)
erlang
io:format("~s~n", [join(Fruit)]).

% ------

join([]) -> "";
join([W|Ws]) -> join(Ws, W).

join([], S) -> S;
join([W], S) -> join([], S ++ " and " ++ W);
join([W|Ws], S) -> join(Ws, S ++ ", " ++ W).
%% According to the reference manual, "string is not a data type in Erlang."
%% Instead it has lists of integers. But I/O functions in general accept
%% IO lists, where an IO list is either a list of IO lists or an integer.
%% This gives you O(1) string concatenation.

-module(commalist).
-export([join/1]).

join([]) -> "";
join([W]) -> W;
join([W1, W2]) -> [W1, " and ", W2];
join([W1, W2, W3]) -> [W1, ", ", W2, ", and ", W3];
join([W1|Ws]) -> [W1, ", ", join(Ws)].

ocaml
let join list =
let rec join' list acc =
match list with
| [] -> ""
| [single] -> single
| one::[two] ->
if acc = "" then one ^ " and " ^ two
else acc ^ one ^ ", and " ^ two
| first::others -> join' others (acc ^ first ^ ", ")
in
join' list ""
csharp
using System.Collections.Generic;
using System.Linq;

public class CSharpListToEnglishList {
public string JoinAsEnglishList (List<string> words) {
switch (words.Count) {
case 0: return "";
case 1: return words[0];
case 2: return string.Format("{0} and {1}", words.ToArray());
default:
return JoinAsEnglishList( new List<string>() {
string.Join(", ", words.Take(words.Count - 1).ToArray()) + ",",
words.Last()
});
}
}
// Driver...
public static void Main() {
var joiner = new CSharpListToEnglishList();
System.Console.WriteLine(
joiner.JoinAsEnglishList(new List<string>() { "Apple", "Banana", "Carrot", "Orange" }) );
System.Console.WriteLine(
joiner.JoinAsEnglishList(new List<string>() { "Apple", "Banana", "Carrot" }) );
System.Console.WriteLine(
joiner.JoinAsEnglishList(new List<string>() { "One", "Two" }) );
System.Console.WriteLine(
joiner.JoinAsEnglishList(new List<string>() { "Lonely" }) );
System.Console.WriteLine(
joiner.JoinAsEnglishList(new List<string>()) );
}
}
php
function ImplodeToEnglish($array) {
// sanity check
if (!$array || !count ($array))
return "";

// get last element
$last = array_pop($array);

// if it was the only element - return it
if (!count ($array))
return $last;

return implode(", ", $array)." and ".$last;
}
//example
ImplodeToEnglish(array("Apple", "Banana")); // returns: Apple and Banana
haskell
join [] = ""
join [x] = x
join [x,y] = x ++ " and " ++ y
join [x,y,z] = x ++ ", " ++ y ++ ", and " ++ z
join (x:xs) = x ++ ", " ++ join xs
clojure
(defn join [lst]
(cond
(= (count lst) 0) ""
(= (count lst) 1) (first lst)
(= (count lst) 2) (str (first lst) " and " (second lst))
(> (count lst) 2) (loop [lst lst sb (StringBuilder.)]
(if (empty? lst)
(.toString sb)
(recur (rest lst) (.append sb (cond
(> (count lst) 2) (str (first lst) ", ")
(> (count lst) 1) (str (first lst) ", and ")
(= (count lst) 1) (str (first lst)))))))))
(defn join
([lst]
(join lst false))
([lst is-long]
(condp = (count lst)
0 ""
1 (first lst)
2 (str (first lst) (if is-long ",") " and " (second lst))
(str (first lst) ", " (join (rest lst) true)))))
(defn join [& a]
(case (count a)
0 ""
1 (-> a first str)
2 (->> a (interpose " and ") (apply str))
(apply str (concat (interpose ", " (butlast a)) [", and " (last a)]))))
fantom
join := |List list -> Str|
{
switch(list.size)
{
case 0: return ""
case 1: return list[0]
case 2: return list.join(" and ")
default: return list[0..-2].join(", ") + ", and " + list[-1]
}
}

echo(join(["Apple", "Banana", "Carrot"]))
echo(join(["One", "Two"]))
echo(join(["Lonely"]))
echo(join([,]))

Produce the combinations from two lists

Given two lists, produce the list of tuples formed by taking the combinations from the individual lists. E.g. given the letters ["a", "b", "c"] and the numbers [4, 5], produce the list: [["a", 4], ["b", 4], ["c", 4], ["a", 5], ["b", 5], ["c", 5]]
ruby
common = [] ; [4, 5].each {|n| ['a', 'b', 'c'].each {|l| common << [l, n]}}
[4, 5].product(['a', 'b', 'c']).map(&:reverse)
java
List<String> combinations = new ArrayList<String>();

for (int number : numbers)
for (String letter : letters)
combinations.add(letter + ":" + Integer.toString(number));
SortedSet<AbstractMap.SimpleImmutableEntry<String, Integer> > combinations =
new TreeSet<AbstractMap.SimpleImmutableEntry<String, Integer> >(new CombinationComparator());

for (int number : numbers)
for (String letter : letters)
combinations.add(new AbstractMap.SimpleImmutableEntry<String, Integer>(letter, Integer.valueOf(number)));
perl
@letters = qw(a b c);
@numbers = (4, 5);
@list = map { $number=$_; map [$_, $number], @letters; } @numbers;
@letters = qw(a b c);
@numbers = (4, 5);

for $number (@numbers) {
for $letter (@letters) {
push @list, [$letter, $number];
}
}
groovy
letters = ['a', 'b', 'c']
numbers = [4, 5]
combos = [letters, numbers].combinations()
scala
val combinations =
(numbers foldLeft List[Pair[String, Int]]()) { (acc : List[Pair[String, Int]], number : Int) =>
acc ::: (letters map { (letter : String) => Pair(letter : String, number : Int) }) }
def product(set1 : List[_], set2 : List[_]) : List[Pair[_, _]] =
{
val p = new mutable.ArrayBuffer[Pair[_, _]]()
for (e1 <- set1) for (e2 <- set2) p += Pair(e1, e2)
p.toList
}

// ------

val combinations =
product(numbers, letters) map { (c) => c match { case Pair(number, letter) => Pair(letter, number) } }
val letters = List('a', 'b', 'c')
val numbers = List(4, 5)
for { l <- letters; n <- numbers } yield (l,n)
python
[(x, y) for y in [1,2] for x in ['a','b','c']]
import itertools
[x for x in itertools.product(["a", "b", "c"], [4, 5])]
cpp
Specialized::StringCollection^ combinations = gcnew Specialized::StringCollection;

for each(int number in numbers)
for each(String^ letter in letters)
combinations->Add(makeCombo(letter, number));
string letters[] = { "a", "b", "c" };
int numbers[] = { 4, 5 };
list<pair<string,int> > combo;

for (int n = 0; n < sizeof numbers / sizeof *numbers; n++)
for (int l = 0; l < sizeof letters / sizeof *letters; l++)
combo.push_back(make_pair(letters[l], numbers[n]));

cout << combo << endl;
fsharp
let combinations = (List.fold_left (fun acc number -> acc @ (List.map (fun letter -> (letter, number)) letters)) [] numbers)
let combinations aa bb =
aa
|> List.map (fun a -> bb |> List.map (fun b -> (a, b)))
|> List.concat
erlang
Combinations =
lists:foldl(fun (Number, Acc) -> Acc ++ lists:map(fun (Letter) -> {Letter, Number} end, Letters) end, [], Numbers),
Combinations = lists:keysort(2, sofs:to_external(sofs:product(sofs:set(Letters), sofs:set(Numbers))))
[[A, B] || A <- ["a", "b", "c"], B <- [4, 5]].

ocaml
let combinations =
let l1 = ["a"; "b"; "c"]
and l2 = [4; 5] in
List.rev (
List.fold_left (fun acc y ->
List.fold_left (fun acc2 x ->
(x, y)::acc2
) acc l1
) [] l2
)
csharp
using System.Collections.Generic;
public class ListCombiner {
public static void Main() {
var letters = new List<char>() { 'a', 'b', 'c' };
var numbers = new List<int>() { 1, 2, 3 };

// result is a list that contaings lists of objects
var result = new List<List<object>>();
foreach (var l in letters) {
foreach (var n in numbers) {
result.Add(new List<object>() { l, n });
}
}
}
}
php
foreach ($short as $s) {
foreach ($long as $l) {
$list[] = array($l, $s);
}
}
haskell
comb :: [(String, Int)]
comb = do
b <- [4,5]
a <- ["a","b","c"]
return (a,b)

main = mapM_ print comb
comb :: [(String, Int)]
comb = [(a, b) | b <- [4,5], a <- ["a","b","c"]]

main = print comb
clojure
(defn combine [lst1 lst2]
(mapcat (fn [x] (map #(list % x) lst1)) lst2))
(mapcat (fn [x] (map #(list % x) ["a", "b", "c"])) [4, 5])
(for [x [4 5] y ["a" "b" "c"]] [y x])
fantom
[4,5].each |Int i| { ["a","b","c"].each |Str s| { r.add([i,s]) } }

From a List Produce a List of Duplicate Entries

Taking a list:
["andrew", "bob", "chris", "bob"]

Write the code to produce a list of duplicates in the list:
["bob"]
ruby
foo = ['andrew', 'bob', 'chris', 'bob']
foo.inject({}) {|h,v| h[v]=h[v].to_i+1; h}.reject{|k,v| v==1}.keys
xs = ['andrew', 'bob', 'chris', 'bob']
xs.uniq.select { |x| xs.count(x) > 1 }
java
List listOfDuplicates = new ArrayList(Arrays.asList(new String[]{"andrew", "bob", "chris", "bob"}));

Set set = new HashSet(listOfDuplicates);
for (Object element : set)
listOfDuplicates.remove(element);
perl
my @input = ("andrew", "bob", "chris", "bob", "bob");

my %input_count;
my @output = grep { $input_count{$_}++; $input_count{$_} == 2 } @input;
groovy
def input = ["andrew", "bob", "chris", "bob"]

def output = input.findAll{input.count(it)>1}.unique()

assert output == ["bob"]
scala
List("andrew", "bob", "chris", "bob")
.groupBy(identity)
.filter( person => person._2.size > 1)
.map(_._1)
val l = List("andrew", "bob", "chris", "bob")
l.diff(l.distinct)
python
import itertools
input = ["andrew", "bob", "chris", "bob"]
input.sort()
output = [k for k, g in itertools.groupby(input, lambda x: x) if len(list(g)) > 1]
cpp
vector<string> lst = { "andrew", "bob", "chris", "bob" };
vector<string> lst_no_dups;
vector<string> tmp;
vector<string> dups;

sort(lst.begin(), lst.end());
unique_copy(lst.begin(), lst.end(), back_inserter(lst_no_dups));
set_difference(lst.begin(), lst.end(),
lst_no_dups.begin(), lst_no_dups.end(),
back_inserter(tmp));
unique_copy(tmp.begin(), tmp.end(), back_inserter(dups));

cout << dups << endl;
list<string> lst = { "andrew", "bob", "chris", "bob" };
map<string,int> num_identical;
list<string> dups;

for (auto &s: lst)
num_identical[s]++;
for (auto &n: num_identical)
if (n.second > 1)
dups.push_back(n.first);
cout << dups << endl;
fsharp
["andrew"; "bob"; "chris"; "bob"]
|> Seq.countBy id
|> Seq.filter (fun (k,n) -> n > 1)
|> Seq.map fst
|> Seq.toList
erlang
{_, Result} = lists:foldl(
fun(X, {Uniq, Dupl}) -> case lists:member(X, Uniq) of
true -> {Uniq,[X | Dupl]};
_ -> {[X | Uniq], Dupl}
end
end,
{[], []},
List),
Fun = fun
([X | Xs], F) -> case lists:member(X, Xs) of
true -> [X | F(Xs, F)];
_ -> F(Xs, F)
end;
([], _) -> []
end,
Result = Fun(List, Fun).
ocaml
let rem v lst =
let rec aux acc = function
| [] -> List.rev acc
| x::xs ->
if compare v x = 0
then aux acc xs
else aux (x::acc) xs
in
aux [] lst

(** in case of a match, returns a list with the duplicate(s) removed *)
let rec mem_rem v lst =
let rec aux acc = function
| [] -> None
| x::xs ->
if compare v x = 0
then Some(List.rev_append acc (rem v xs))
else aux (x::acc) xs
in
aux [] lst

let duplicates lst =
let rec aux acc = function
| [] -> List.rev acc
| x::xs ->
match mem_rem x xs with
| Some ret -> aux (x::acc) ret
| None -> aux acc xs
in
aux [] lst

let () =
let lst = ["andrew"; "bob"; "chris"; "bob"; "mike"; "peter"; "bob"] in
let dup = duplicates lst in
List.iter print_endline dup
(* Using standard (functorized) sets *)

module SetTools(ASet: Set.S) =
struct
let find_duplicates l =
let rec aux l seen acc =
match l with
| [] -> acc
| h :: q ->
if ASet.mem h seen then
aux q seen (h :: acc)
else
aux q (ASet.add h seen) acc in
aux l (ASet.empty) []
end

module StringSet = Set.Make(String)

module StringSetTools = SetTools(StringSet)

StringSetTools.find_duplicates ["andrew"; "bob"; "chris"; "bob"];;
csharp
List<String> values = new List<string> {"andrew", "bob", "chris", "bob"};

var duplicates = values
.GroupBy(i => i)
.Where(j => j.Count() > 1)
.Select(s => s.Key);
foreach (var duplicate in duplicates)
{
Console.WriteLine(duplicate);
}
php
$arr = array('andrew', 'bob', 'chris', 'bob', 'chris', 'john', 'mary', 'lucy');

function match($a, $b)
{
// This is a separate function so you could include checking
// with loose comparisons or lowercase both strings, etc.
return $a === $b;
}

$results = array();

sort($arr);

for($i = 0; $i < count($arr) - 1; $i++)
{
if (match($arr[$i], $arr[$i+1]))
{
$results[] = $arr[$i];
$i++;
}
}
print_r($results);
$arr = array('lucy', 'andrew', 'lucy', 'bob', 'chris', 'bob', 'chris', 'john', 'mary');

function match($a, $b)
{
// This is a separate function so you could include checking
// with loose comparisons or lowercase both strings, etc.
return $a === $b;
}

$results = array();

for($i = 0; $i < count($arr); $i++)
{
if (isset($results[$arr[$i]]))
{
$results[$arr[$i]]++;
}
else
{
$results[$arr[$i]] = 0;
}
}

$out = array();

foreach($results as $name => $count)
{
echo $name . ':' . $count . '<br />';
if ($count > 0)
{
$out[] = $name;
}
}

print_r($out);
<?php
$array = array("andrew", "bob", "chris", "bob");
$counts = array_count_values($array);

$duplicates = array_filter(
array_unique($array),
function($key) use ($counts) {
return $counts[$key] > 1;
}
);
?>
haskell
import Data.List

input = ["andrew", "bob", "chris", "bob"]
output = [ head l | l <- group (sort input), length l > 1]
clojure
(->> '("andrew" "bob" "chris" "bob")
(group-by identity)
(filter #(> (count (second %)) 1))
(map first))
fantom
nameCounts := Str:Int[:] { def = 0 }
["andrew", "bob", "chris", "bob"].each |Str v| { nameCounts[v]++ }
results := nameCounts.findAll |Int v, Str k->Bool| { v > 1 }.keys
echo(results.join(","))