View Subcategory

Gather together corresponding elements from multiple lists

Given several lists, gather together the first element from every list, the second element from every list, and so on for all corresponding index values in the lists. E.g. for these three lists, first = ['Bruce', 'Tommy Lee', 'Bruce'], last = ['Willis', 'Jones', 'Lee'], years = [1955, 1946, 1940] the result should produce 3 actors. The middle actor should be Tommy Lee Jones.
perl
my @first = ('Bruce', 'Tommy Lee', 'Bruce');
my @last = ('Willis', 'Jones', 'Lee');
my @years = (1955, 1946, 1940);

my @actors;

my $max = scalar @first;
for my $index (0 .. $max) {
push @actors, [ $first[$index], $last[$index], $years[$index] ];
};
cpp
array<String^>^ first = {"Bruce", "Tommy Lee", "Bruce"}; array<String^>^ last = {"Willis", "Jones", "Lee"}; array<String^>^ years = {"1955", "1946", "1940"};

array<String^>^ result = zip<String^>(",", first, last, years);
list<string> first = { "Bruce", "Tommy Lee", "Bruce" };
list<string> last = {"Willis", "Jones", "Lee"};
list<int> years = {1955, 1946, 1940};
list<tuple<string,string,int> > actors;

for (firstIt = first.begin(), lastIt = last.begin(), yearIt = years.begin();
firstIt != first.end() && lastIt != last.end() && yearIt != years.end();
++firstIt, ++lastIt, ++yearIt)
actors.push_back(make_tuple(*firstIt, *lastIt, *yearIt));
csharp
String[] first = { "Bruce", "Tommy Lee", "Bruce" };
String[] last = { "Willis", "Jones", "Lee" };
int[] years = { 1955, 1946, 1940 };
var actors = first.Zip(last, (f, l) => Tuple.Create(f, l)).Zip(years, (t, y) => Tuple.Create(t.Item1, t.Item2, y)).ToArray();
Debug.Assert(actors[1].Equals(Tuple.Create("Tommy Lee", "Jones", 1946)));

List Combinations

Given two source lists (or sets), generate a list (or set) of all the pairs derived by combining elements from the individual lists (sets). E.g. given suites = ['H', 'D', 'C', 'S'] and faces = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'], generate the deck of 52 cards, confirm the deck size and check it contains an expected card, say 'Ace of Hearts'.
perl
@suites = qw(H D C S);
@faces = qw(2 3 4 5 6 7 8 9 10 J Q K A);
@deck = map { $suite=$_; map $suite.$_, @faces; } @suites;
print 'checking deck size: ' . (@deck == 52 ? 'pass' : 'fail') . "\n";
print 'deck contains "Ace of Hearts": ' . (grep(/^HA$/, @deck) ? 'true' : 'false') . "\n";
cpp
Specialized::StringCollection^ cards = gcnew Specialized::StringCollection;

for each(String^ suite in suites)
for each(String^ face in faces)
cards->Add(makeCard(suite, face));

Console::WriteLine("Deck has {0} cards", cards.Count);
if (cards->Contains(makeCard("h", "A"))) Console::WriteLine("Deck contains 'Ace of hearts'"); else Console::WriteLine("'Ace of hearts' not in deck");
auto suites = {"h", "d", "c", "s"};
auto faces = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
list<card> cards;

for (auto s: suites)
for (auto f: faces)
cards.push_back(make_pair(s,f));

cout << "Deck has " << cards.size() << " cards." << endl;

card ace_of_harts = make_pair("h", "A");
if (end(cards) != find_if(begin(cards), end(cards),
[&](const card& c) { return c == ace_of_harts; }))
cout << "Deck contain 'Ace of Harts'" << endl;
else
cout << "Deck lacks 'Ace of Harts'" << endl;
csharp
using System;
using System.Collections.Generic;
using System.Linq;

namespace Combinations
{
class Program
{
public static void Main(string[] args)
{
// Define the given lists
// Since List`1 implements the interface IEnumerable`1, this can easily be redefined as List`1.
IEnumerable<string> suites = new string[] { "H", "D", "C", "S" };
IEnumerable<string> faces = new string[] { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };

// LINQ Query to perform a Cartesian product and create an anonymous type to hold the results.
// "var" is required to define this as an IEnumerable`1
var deck =
from suite in suites // For each suite in suites
from face in faces // Match it with a face in face.
select new
{
Suite = suite,
Face = face
};

// Verify the count (uses LINQ extension)
if (deck.Count() == 52)
{
Console.WriteLine("Count matches!");
}

// Verify that the Ace of Hearts is in the deck (uses LINQ extension)
if (deck.Contains(new {Suite = "H", Face = "A"}))
{
Console.WriteLine("Ace of Hearts found!");
}

// Example of how to iterate through the list.
// "var" here is required since we are using an anonymous type
foreach(var card in deck)
{
Console.WriteLine("Suite: {0} Face: {1}", card.Suite, card.Face);
}

// If you desire to work with a List`1, you can convert this to a normal list at any time:
Console.WriteLine("\nConverting to list!");
var list = deck.ToList();
Console.WriteLine("Suite: {0} Face: {1}", list[5].Suite, list[5].Face);
Console.WriteLine("List count: {0}", list.Count); // 52

Console.ReadLine();
}
}
}

Perform an operation on every item of a list

Perform an operation on every item of a list, e.g.
for the list ["ox", "cat", "deer", "whale"] calculate
the list of sizes of the strings, e.g. [2, 3, 4, 5]
perl
my @list = qw{ox cat deer whale};

my @lengths = map {length($_)} @list;

print "@list\n";
print "@lengths\n";
cpp
list<string> words;

words.push_back("ox");
words.push_back("cat");
words.push_back("deer");
words.push_back("whale");

for (list<string>::iterator it = words.begin(); it != words.end(); ++it)
cout << it->size() << ' ';
cout << endl;
auto words = { "ox", "cat", "deer", "whale" };
list<size_t> word_sizes;

transform(begin(words),
end(words),
back_inserter(word_sizes),
[](const string& s) { return s.size(); });
csharp
using System.Collections.Generic;
public class OperationOnEach {
public static void Main() {
var list = new List<string>() { "ox", "cat", "deer", "whale" };
list.ForEach( System.Console.WriteLine );
}
}

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.
perl
use Scalar::Util qw(looks_like_number);
my @things = ('hello',25,3.14,scalar(localtime(time)));
my @numbers;
my @others;
for ( @things ) {
if ( looks_like_number $_ ) {
push @numbers, $_;
} else {
push @other, $_;
}
}
cpp
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;
#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'
}
csharp
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) );
}

}