View Problem
Split a list of things into numbers and non-numbers
Given a list that might contain e.g. a string, an integer, a float and a date,
split the list into numbers and non-numbers.
Submit a new solution for ruby, cpp, fsharp, erlang ...
There are 9 other solutions in additional languages (fantom, haskell, java, ocaml ...)
split the list into numbers and non-numbers.
cpp boost::variant
typedef variant<int,float,string,date> dynamic;
class is_number : public static_visitor<bool>
{
public:
bool operator()(int &) const {
return true;
}
bool operator()(float &) const {
return true;
}
bool operator()(string &) const {
return false;
}
bool operator()(date &) const {
return false;
}
};
int main()
{
list<dynamic> lst;
list<dynamic> numbers;
list<dynamic> non_numbers;
lst += "hello", 3.14f, 42, date(2011,Aug,23);
BOOST_FOREACH(dynamic v, lst)
if (apply_visitor(is_number(), v))
numbers += v;
else
non_numbers += v;
class is_number : public static_visitor<bool>
{
public:
bool operator()(int &) const {
return true;
}
bool operator()(float &) const {
return true;
}
bool operator()(string &) const {
return false;
}
bool operator()(date &) const {
return false;
}
};
int main()
{
list<dynamic> lst;
list<dynamic> numbers;
list<dynamic> non_numbers;
lst += "hello", 3.14f, 42, date(2011,Aug,23);
BOOST_FOREACH(dynamic v, lst)
if (apply_visitor(is_number(), v))
numbers += v;
else
non_numbers += v;
cpp boost::any
#include <iostream>
#include <list>
#include <boost/any.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/foreach.hpp>
using namespace boost;
using namespace boost::gregorian;
using namespace std;
int main()
{
list<any> lst;
list<any> numbers;
list<any> non_numbers;
lst.push_back(string("hello"));
lst.push_back(42);
lst.push_back(3.14f);
lst.push_back(date(day_clock::local_day()));
BOOST_FOREACH(const any &a, lst)
try
{
numbers.push_back(any_cast<int>(a));
}
catch (bad_any_cast &e)
{
try
{
numbers.push_back(any_cast<float>(a));
}
catch (bad_any_cast &e)
{
non_numbers.push_back(a);
}
}
// float and int are now in 'numbers' and the rest in 'non_numbers'
}
#include <list>
#include <boost/any.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/foreach.hpp>
using namespace boost;
using namespace boost::gregorian;
using namespace std;
int main()
{
list<any> lst;
list<any> numbers;
list<any> non_numbers;
lst.push_back(string("hello"));
lst.push_back(42);
lst.push_back(3.14f);
lst.push_back(date(day_clock::local_day()));
BOOST_FOREACH(const any &a, lst)
try
{
numbers.push_back(any_cast<int>(a));
}
catch (bad_any_cast &e)
{
try
{
numbers.push_back(any_cast<float>(a));
}
catch (bad_any_cast &e)
{
non_numbers.push_back(a);
}
}
// float and int are now in 'numbers' and the rest in 'non_numbers'
}
erlang
% Wrapped call to the auxiliary function
number_split(Xs) ->
number_split(Xs, [], []).
% The auxiliary function
number_split([], Num, NonNum) ->
{Num, NonNum};
number_split([X|Xs], Num, NonNum) ->
case is_number(X) of
true ->
number_split(Xs, [X|Num], NonNum);
false ->
number_split(Xs, Num, [X|NonNum])
end.
number_split(Xs) ->
number_split(Xs, [], []).
% The auxiliary function
number_split([], Num, NonNum) ->
{Num, NonNum};
number_split([X|Xs], Num, NonNum) ->
case is_number(X) of
true ->
number_split(Xs, [X|Num], NonNum);
false ->
number_split(Xs, Num, [X|NonNum])
end.
csharp .NET 3.5
using System;
using System.Collections.Generic;
using System.Linq;
// AFAIK, there just isn't a good way to do this in C#
public class ListSplitter {
public static bool IsNumeric(object o) {
var d = new Decimal();
return decimal.TryParse(o.ToString(), out d);
}
public static void Main() {
var list = new List<object>() { "foo", DateTime.Now, 1, "bar", 2.4 };
// the Where method does the work...
var numbers = list.Where( el => IsNumeric(el) );
var nonNumbers = list.Where( el => ! IsNumeric(el) );
}
}
using System.Collections.Generic;
using System.Linq;
// AFAIK, there just isn't a good way to do this in C#
public class ListSplitter {
public static bool IsNumeric(object o) {
var d = new Decimal();
return decimal.TryParse(o.ToString(), out d);
}
public static void Main() {
var list = new List<object>() { "foo", DateTime.Now, 1, "bar", 2.4 };
// the Where method does the work...
var numbers = list.Where( el => IsNumeric(el) );
var nonNumbers = list.Where( el => ! IsNumeric(el) );
}
}
clojure
(def jumble [3 "Bill" 5.7 '("A" "B" "C")]) ; int, string, float, list
(defn numberNonNumberSorter [jumbledList]
(if (empty? jumbledList)
(hash-map :numbers [], :nonnumbers []) ; recursion base case - return two empty lists
(let [head (first jumbledList)] ; let <head> be the first element in the list
(let [tailresult (numberNonNumberSorter (rest jumbledList))] ; tailresult applies recursively to the remainder
(if (number? head) ; is head a number?
(hash-map
:numbers (cons head (tailresult :numbers)) ; add <head> to the numbers
:nonnumbers (tailresult :nonnumbers)) ; leave nonnumbers the same
(hash-map
:numbers (tailresult :numbers) ; leave numbers the same
:nonnumbers (cons head (tailresult :nonnumbers))) ; add <head> to nonnumbers
)
)
)
)
)
(println (numberNonNumberSorter jumble))
; -> {:nonnumbers (Bill (A B C)), :numbers (3 5.7)}
(defn numberNonNumberSorter [jumbledList]
(if (empty? jumbledList)
(hash-map :numbers [], :nonnumbers []) ; recursion base case - return two empty lists
(let [head (first jumbledList)] ; let <head> be the first element in the list
(let [tailresult (numberNonNumberSorter (rest jumbledList))] ; tailresult applies recursively to the remainder
(if (number? head) ; is head a number?
(hash-map
:numbers (cons head (tailresult :numbers)) ; add <head> to the numbers
:nonnumbers (tailresult :nonnumbers)) ; leave nonnumbers the same
(hash-map
:numbers (tailresult :numbers) ; leave numbers the same
:nonnumbers (cons head (tailresult :nonnumbers))) ; add <head> to nonnumbers
)
)
)
)
)
(println (numberNonNumberSorter jumble))
; -> {:nonnumbers (Bill (A B C)), :numbers (3 5.7)}
Submit a new solution for ruby, cpp, fsharp, erlang ...
There are 9 other solutions in additional languages (fantom, haskell, java, ocaml ...)




