You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
3.0 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma once
#include <map>
#include <string>
#include <variant>
#include <vector>
#include <cassert>
// 表格中的数据类型
using DataTableValue = std::variant<int, double, std::string>;
/**
* 表格中的列
*/
class DataColumn
{
public:
enum class DataType
{
Int,
Double,
String,
};
DataColumn(const std::string& m_name, DataType m_dataType)
: m_name(m_name), m_dataType(m_dataType)
{
}
const std::string& getName() const
{
return m_name;
}
void setName(const std::string& name)
{
m_name = name;
}
DataType getDataType() const
{
return m_dataType;
}
void setDataType(DataType dataType)
{
m_dataType = dataType;
}
private:
std::string m_name;
DataType m_dataType;
};
/**
* 表格中的行
*/
class DataRow
{
public:
/**
* 通过列名设置值
*
* \param columnName 列名
* \param value 值
*/
void setValue(const std::string& columnName, const DataTableValue& value)
{
m_values[columnName] = value;
}
/**
* 获取指定列的值
*
* \param columnName 列名
* \return
*/
const DataTableValue &value(const std::string& columnName) const
{
return m_values.at(columnName);
}
/**
* 获取指定列的值
*
* \param columnName 列名
* \return
*/
DataTableValue& operator[](const std::string& columnName)
{
return m_values[columnName];
}
private:
std::map<std::string, DataTableValue> m_values;
};
/**
* 表格
* \note
* 这个表格类还很不完善,主要有以下几点
* 1、设置值时没有根据列头做类型校验
* 2、添加列时没有去所有行里面添加值
* 3、没有移除列等操作
* 4、没有对下标有效性进行校验
* 5、其它暂时没细想
* 虽然不够完善,但是不妨碍使用,主要用在统计一类功能上面
*/
class DataTable
{
public:
/**
* 添加列
*
* \param column 列
*/
void addColumn(const DataColumn& column)
{
m_columns.push_back(column);
}
/**
* 获取列数
*
* \return 表的列数
*/
size_t columnCount() const
{
return m_columns.size();
}
/**
* 添加一行数据
*
* \param row 行
*/
void addRow(const DataRow& row)
{
m_rows.push_back(row);
}
/**
* 获取表总行数
*
* \return
*/
size_t rowCount() const
{
return m_rows.size();
}
/**
* 根据行列下标获取值
*
* \param rowIndex 行下标从0开始
* \param columnIndex 列下标从0开始
* \return 对应的值
*/
const DataTableValue& getValue(int rowIndex, int columnIndex) const
{
assert(rowIndex >= 0);
assert(columnIndex >= 0);
return m_rows[rowIndex].value(m_columns[columnIndex].getName());
}
/**
* 根据行列下标设置值
*
* \param rowIndex 行下标从0开始
* \param columnIndex 列下标从0开始
* \param value 值
*/
void setValue(int rowIndex, int columnIndex, const DataTableValue& value)
{
assert(rowIndex >= 0);
assert(columnIndex >= 0);
m_rows[rowIndex].setValue(m_columns[columnIndex].getName(), value);
}
/**
* 获取列头
*
* \return 所有列组成的头
*/
std::vector<std::string> getColumnHeaders() const
{
std::vector<std::string> headers;
for (const auto& column : m_columns) {
headers.push_back(column.getName());
}
return headers;
}
private:
std::vector<DataColumn> m_columns;
std::vector<DataRow> m_rows;
};