LoginSignup
3
3

More than 5 years have passed since last update.

SQLのJOINみたいなことをプログラムで超簡単にやる方法

Last updated at Posted at 2014-05-05

LINQ for C++ というライブラリーにjoinというメソッドがあります。

これを使うとSQLのJOINみたいなこと超簡単にできます。

やっつけで作ったサンプルですが、join_test.cppのmain()の中で使っています。

あと、このライブラリーはモダンな作りでヘッダー・オンリーなので使いやすいです。

join_test.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <utility>
#include <cstdlib>
#include "cpplinq.hpp"

using namespace std;

struct test_data
{
    test_data() : string_code(), numeric_data()
    {}

    test_data(string string_code0, long numeric_data0) : string_code(string_code0), numeric_data(numeric_data0)
    {}

    string string_code;
    long numeric_data;
};

void read_file(vector<test_data>& input, const char *filename)
{
    ifstream in(filename);

    string line;
    while (getline(in, line)) {
        size_t pos = line.find('\t');
        if (pos != string::npos) {
            long numeric_data = atol(&line[pos] + 1);
            input.emplace_back(line.substr(0, pos), numeric_data);
        }
    }
}

int main()
{
    using namespace cpplinq;

    vector<test_data> input1, input2;

    read_file(input1, "input1.tsv");
    read_file(input2, "input2.tsv");

    auto query = from(input1)
        >> join (
            from(input2),
            [](test_data const& left) { return left.string_code; },
            [](test_data const& right) { return right.string_code; },
            [](test_data const& left, test_data const& right) { return make_pair(left.numeric_data, right.numeric_data); })
        >> to_vector()
        ;

    for (auto const& row : query) {
        cout << row.first << "\t" << row.second << endl;
    }

    return 0;
}

ビルド用のファイル

Jamroot
import testing ;

run join_test.cpp
    :
    :
    : <toolset>gcc:<cxxflags>-std=gnu++0x <toolset>clang:<cxxflags>-std=c++11
    ;

テストデータ作成ツール

gen_test_data.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import uuid
import random
from optparse import OptionParser

parser = OptionParser()
parser.add_option("-n", "--num", dest="num", default="100")
(options, args) = parser.parse_args()

data = [ (uuid.uuid4(), num) for num in range(0, int(options.num)) ]

random.shuffle(data)
with open('input1.tsv', 'wb') as f:
    for row in data:
        print >>f, "%s\t%d" % (row[0], row[1])

random.shuffle(data)
with open('input2.tsv', 'wb') as f:
    for row in data:
        print >>f, "%s\t%d" % (row[0], row[1])

使い方の例

./gen_test_data.py --num=100
time bjam variant=release -a

同じようなライブラリーで、Ovenというのを使ってもできそうな気がしますが、こちらは試してないです。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3