エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

MapでSummary

えーと。リンク先の内容に付加するような情報はほとんどないんですが。
ただちょっと。気になるところがあって。自分なりに自分の使える言語で書き下してみた。

C++98

あれ?C++11のひとつ前の標準ってC++98でいいんでしたっけ?C++03とかになるんでしたっけ?

#include <iostream>
#include <string>
#include <map>

struct Datum
{
    std::string code;
    std::string name;
    int         value;
};

class Summary : public std::map<std::string, int> 
{
public:
    typedef std::map<std::string, int> super;

    template<typename Iterator>
    void summarizeByCode(Iterator begin, Iterator end)
    {
        clear();
        for(Iterator i = begin; i != end; ++i)
        {
            (*this)[i->code] += i->value;
        }
    }

};

int main(int, char* [])
{
    Datum data[] = { { "A01", "hoge", 100 },
                     { "A01", "piyo", 200 },
                     { "A02", "hoge", 300 },
                     { "A03", "hoge", 400 },
                     { "A03", "piyo", 500 } };

    Summary summary;

    summary.summarizeByCode(data, data + sizeof(data) / sizeof(data[0]));

    for(Summary::const_iterator i = summary.begin(); i != summary.end(); ++i)
    {
        std::cout << i->first << ", " << i->second << "\n";
    }

    return 0;
}

C++11

#include <iostream>
#include <string>
#include <map>
#include <algorithm>

struct Datum
{
    std::string code;
    std::string name;
    int         value;
};

typedef std::map<std::string, int> Summary;

int main(int, char* [])
{
    Datum data[] = { { "A01", "hoge", 100 },
                     { "A01", "piyo", 200 },
                     { "A02", "hoge", 300 },
                     { "A03", "hoge", 400 },
                     { "A03", "piyo", 500 } };

    Summary summary;

    std::for_each(std::begin(data), std::end(data), [&](const Datum& d) { summary[d.code] += d.value; });

    std::for_each(std::begin(summary), std::end(summary), [](const Summary::value_type& value) { std::cout << value.first << ", " << value.second << "\n"; });

    return 0;
}

の〜。C++11の威力が半端ない。

Ruby

Datum = Struct.new(:code, :name, :value)

class Hash
  def summarizeByCode(data)
    data.each do |d|
      self[d.code] ||= 0
      self[d.code] += d.value
    end
  end
end

data = [ Datum.new("A01", "hoge", 100),
         Datum.new("A01", "piyo", 200),
         Datum.new("A02", "hoge", 300),
         Datum.new("A03", "hoge", 400),
         Datum.new("A03", "piyo", 500) ]

summary = {}
summary.summarizeByCode(data);

summary.each { |key, value| puts "#{key}, #{value}" }

で、なにが気になった?

なんかよくわかんないんですけど、なんかしっくりこないところが。なんだろ?