简体   繁体   English

将STL映射打印为表格

[英]Print a STL Map as a table

I have a map defined as map<string, vector<double> > . 我有一个定义为map<string, vector<double> >

How do I print this as a table. 如何将其打印为表格。 I want the key of the map to be the title row of the table and the each column of the table will be the vector 我希望地图的键是表格的标题行,表格的每一列都是vector

Say my initial map was 说我的初始地图是

hash = {
  "a": [1, 2, 3],
  "b": [1, 2, 3]
}

I want this printed as 我希望将此打印为

a b
1 1
2 2
3 3

Flexible for arbitrary columns and variant length 灵活适用于任意列和变长

void print(const map<string, vector<double>> &m)
{
    size_t rows = 0;
    for (auto const &i : m)
    {
        cout << i.first << ' ';
        if (i.second.size() > rows)
            rows = i.second.size();
    }
    cout << endl;
    for (size_t r = 0; r < rows; ++r)
    {
        for (auto const &i : m)
            if (r < i.second.size())
                cout << i.second[r] << " ";
            else
                cout << "  ";
        cout << endl;
    }
}
int main()
{ 
    map<string, vector<double> > m = {
        { "a", { 1, 2, 3}},
        { "b", { 1, 2, 3, 4}},
        { "c", { 1, 2}},
        { "d", { 1}},
        { "e", { 1, 2, 3, 4, 5, 6, 7}}
    };
    print(m);
}

Output 输出量

 a b c d e
 1 1 1 1 1
 2 2 2   2
 3 3     3
   4     4
         5
         6
         7

Live source code. 实时源代码。

Here is a possible implementation using C++11 (here I expect all vectors to have the same size ): 这是使用C ++ 11的可能实现(在这里我希望所有向量的大小都相同 ):

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

void print(std::map<std::string, std::vector<double>> const& m)
{
    // Do nothing for an empty table...
    if (m.begin() == m.end()) { return; }

    for (size_t i = 0; i <= m.begin()->second.size(); i++)
    {
        for (auto const& p : m)
        {
            if (i == 0) { std::cout << p.first << " "; }
            else { std::cout << p.second[i - 1] << " "; }
        }

        std::cout << std::endl;
    }
}

int main()
{
    std::map<std::string, std::vector<double>> m = {
        { "a", { 1, 2, 3, 0 } },
        { "b", { 2, 4, 6, 1 } },
        { "c", { 9, 2, 3, 2 } }
    };

    print(m);
}

And here is a live example . 这是一个生动的例子

This works with vectors with different lengths: 这适用于具有不同长度的向量:

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

using namespace std;

int main()
{

    map<string,vector<double> > hashes;
    double arr[]={1,2,3};
    double arr2[]={1,2,3,4};
    hashes.insert(pair<string,vector<double> >("a",vector<double>(arr,arr+sizeof(arr)/sizeof(double))));
    hashes.insert(pair<string,vector<double> >("b",vector<double>(arr,arr+sizeof(arr)/sizeof(double))));
    hashes.insert(pair<string,vector<double> >("c",vector<double>(arr2,arr2+sizeof(arr2)/sizeof(double))));

    for(auto i: hashes)
    {
        cout<< i.first << ' ';
    }
    cout << endl;
    int max_len=0;
    for(auto i: hashes)
    {
    if(i.second.size()>max_len) max_len=i.second.size();
    }
    for(int h=0; h<max_len; h++)
    {

    for(auto i: hashes)
    {
        if(h>=i.second.size()) cout << "  ";
        else cout << i.second[h] << " ";
    }
    cout << endl;
}
return 0;
}

Output: 输出:

a b c
1 1 1
2 2 2
3 3 3
    4
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

int main()
{
    map<string, vector<double> > m;
    vector<double> a, b, c;
    for (int i = 0; i < 4; ++i) a.push_back(i);
    for (int i = 0; i < 6; ++i) b.push_back(i);
    for (int i = 0; i < 7; ++i) c.push_back(i);
    m["a"] = a;
    m["b"] = b;
    m["c"] = c;

    int n = max(max(a.size(), b.size()), c.size());
    for (map<string, vector<double> >::iterator i = m.begin(); i != m.end(); ++i)
        cout << i->first << ',';
    cout << endl;

    for (int i = 0; i < n; ++i) {
       for (map<string, vector<double> >::iterator it = m.begin(); it != m.end(); ++it)
           cout << (i < it->second.size() ? it->second[i] : 0) << ',';
       cout << endl;
    }
}

I believe there are better ways to do the iteration and to deal with the trailing , . 我相信有更好的方法来完成这样的迭代和应对尾随,

This solution will work for an arbitrary number of columns, each with an arbitrary number of rows. 该解决方案适用于任意数量的列,每列具有任意数量的行。

And column names also with an arbitrary length. 并且列名也具有任意长度。

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

void print(std::map<std::string, std::vector<double>> const& m)
{
    std::vector<size_t> columnWidths;
    std::vector< std::vector<std::string>> columns;
    size_t totalRows = 0;

    // Store all table elements, and the required width of each column
    for ( auto a : m )
    {
       std::vector<std::string> column;
       size_t width = a.first.length();
       column.push_back( a.first );
       size_t rows = 1;

       for ( auto v : a.second )
       {
          ++rows;
          std::string entry = std::to_string(v);
          width = std::max( width, entry.length() );
          column.push_back( entry );
       }
       columnWidths.push_back( width );
       columns.push_back( column );
       totalRows = std::max( totalRows, rows );
    }

    // Print all table elements
    for ( size_t row = 0; row != totalRows; ++row )
    {
        for ( size_t col = 0; col != columns.size(); ++col )
        {
            std::string entry;
            if ( columns[col].size() > row )
            {
                entry = columns[col][row];
            }
            entry.resize( columnWidths[col], ' ' );
            std::cout << entry << ' ';
        }
        std::cout << '\n';
    }
}

int main()
{
    std::map<std::string, std::vector<double>> m =
    {
        { "a", { 1, 2, 3} },
        { "a really really long string", { 1, 2, 3} },
        { "b", { 1, 2, 3, 4, 5 } }
    };

    print(m);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM