160 std::stringstream
ss;
169 if (
ch == std::char_traits<char>::eof())
172 char c =
static_cast<char>(
ch);
178 if (
in.peek() ==
'"')
179 ss <<
static_cast<char>(
in.
get());
190 if (
in.peek() ==
'\n')
227 std::stringstream
ss(line);
293 std::ifstream
file(filename);
295 throw std::runtime_error(
"Cannot open file: " + filename);
338 std::string result =
"\"";
381 for (
size_t i = 0; i <
row.
size(); ++i)
407 for (
size_t i = 0; i < rows.size(); ++i)
429 std::ofstream
file(filename);
431 throw std::runtime_error(
"Cannot open file for writing: " + filename);
468 if (rows.size() == 0)
472 for (
size_t i = 1; i < rows.size(); ++i)
502 for (
size_t i = 0; i < rows.size(); ++i)
505 throw std::out_of_range(
"Column index " + std::to_string(
col_index) +
506 " out of range for row " + std::to_string(i));
541 throw std::invalid_argument(
"Cannot convert '" +
field +
"' to number");
550 return std::stoi(
field);
557 return std::stol(
field);
564 return std::stod(
field);
571 return std::stof(
field);
626 throw std::runtime_error(
"No header set for CsvRow");
632 throw std::out_of_range(
"Column not found: " +
column_name);
639 throw std::out_of_range(
"Index out of range: " + std::to_string(index));
646 if (
header_ ==
nullptr)
return false;
654 template <
typename T>
661 template <
typename T>
728 throw std::runtime_error(
"Cannot open file: " + filename);
765 return CsvRow(std::move(fields));
858template <
typename Pred>
863 for (
size_t i = 0; i < rows.size(); ++i)
883 const std::string & value)
912 for (
size_t i = 0; i < rows.size(); ++i)
918 if (idx < rows(i).
size())
942 for (
size_t i = n; i < rows.size(); ++i)
960 size_t limit = (n < rows.size()) ? n : rows.size();
961 for (
size_t i = 0; i <
limit; ++i)
984 for (
size_t i = 0; i < rows.size(); ++i)
985 for (
size_t j = 0; j < rows(i).size(); ++j)
986 if (rows(i)(j).empty())
994template <
typename Pred>
999 for (
size_t i = 0; i < rows.size(); ++i)
1009template <
typename Pred>
1013 for (
size_t i = 0; i < rows.size(); ++i)
1026 const std::string & value)
1040 for (
size_t i = 0; i < rows.size(); ++i)
1044 const std::string & val = rows(i)(
col_index);
1046 for (
size_t j = 0; j < result.
size(); ++j)
1047 if (result(j) == val) {
found =
true;
break; }
1070 if (rows.size() == 0)
1074 throw std::runtime_error(
"Cannot transpose non-rectangular CSV data");
1080 for (
size_t j = 0; j <
num_cols; ++j)
1083 for (
size_t i = 0; i <
num_rows; ++i)
1107 for (
size_t i = 0; i < rows.size(); ++i)
1142template <
typename T>
1150 for (
size_t i = 0; i < rows.size(); ++i)
1158 for (
size_t i = 0; i <
pairs.
size(); ++i)
1159 for (
size_t j = i + 1; j <
pairs.
size(); ++j)
1170 for (
size_t i = 0; i <
pairs.
size(); ++i)
1188 for (
size_t i = 0; i < rows.size(); ++i)
1191 for (
size_t j = 0; j < result.
size(); ++j)
1193 if (result(j).
size() != rows(i).
size())
continue;
1196 for (
size_t k = 0;
k < rows(i).
size(); ++
k)
1197 if (result(j)(
k) != rows(i)(
k)) {
equal =
false;
break; }
1218template <
typename Func>
1225 for (
size_t i = 0; i < rows.size(); ++i)
1228 for (
size_t j = 0; j < rows(i).size(); ++j)
1276 auto trim = [](
const std::string & s) -> std::string {
1278 while (start < s.size()
and std::isspace(
static_cast<unsigned char>(s[start])))
1281 size_t end = s.size();
1282 while (end > start
and std::isspace(
static_cast<unsigned char>(s[end - 1])))
1285 return s.substr(start, end - start);
1301 const std::string & default_value)
1303 return csv_transform(rows, [&default_value](
const std::string & s) {
1304 return s.empty() ? default_value : s;
1324 size_t max_rows = (left.size() > right.size()) ? left.
size() : right.size();
1326 for (
size_t i = 0; i <
max_rows; ++i)
1331 if (i < left.size())
1332 for (
size_t j = 0; j < left(i).size(); ++j)
1336 if (i < right.size())
1337 for (
size_t j = 0; j < right(i).size(); ++j)
1360 for (
size_t i = 0; i < top.size(); ++i)
1387 for (
size_t i = 0; i < left.size(); ++i)
1392 for (
size_t j = 0; j < right.size(); ++j)
1401 for (
size_t k = 0;
k < left(i).
size(); ++
k)
1404 for (
size_t k = 0;
k < right(j).
size(); ++
k)
1431 for (
size_t k = 0;
k < keys.
size(); ++
k)
1434 for (
size_t i = 0; i < rows.size(); ++i)
1462template <
typename Func>
1469 for (
size_t i = 0; i < rows.size(); ++i)
1472 for (
size_t j = 0; j < rows(i).size(); ++j)
1495 if (rows.size() == 0)
1502 for (
size_t j = 0; j < rows(0).size(); ++j)
1512 for (
size_t i = 1; i < rows.size(); ++i)
Simple dynamic array with automatic resizing and functional operations.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
T & append(const T &data)
Append a copy of data
const Array< std::string > & operator*() const
bool operator!=(const Iterator &other) const
Array< std::string > current_
Iterator(CsvReader *reader, bool at_end)
Lazy CSV reader for large files.
void skip(size_t n)
Skip N rows.
CsvRow next_row()
Read the next row with header access.
Array< std::string > next()
Read the next row as Array.
CsvReader(std::istream &stream, char delimiter=',')
Construct reader from stream.
CsvReader(const std::string &filename, char delimiter=',')
Construct reader from file path.
void reset()
Reset to beginning (only works for file-based readers).
const Array< std::string > & header() const
Get the header (if read).
Array< std::string > read_header()
Read and store the header row.
Array< std::string > header_
size_t rows_read() const
Get number of rows read so far.
bool has_next() const
Check if more rows are available.
bool has_header() const
Check if header was read.
A CSV row with header-based field access.
T get(const std::string &column_name) const
Get field as numeric type by column name.
T get(size_t index) const
Get field as numeric type.
const Array< std::string > * header_
const std::string & at(size_t index) const
Get field by index with bounds checking.
const Array< std::string > * header() const
Get column names (if header set).
const std::string & operator[](const std::string &column_name) const
Get field by column name.
bool empty() const
Check if row is empty.
size_t size() const
Get number of fields.
Array< std::string > fields_
CsvRow(Array< std::string > fields)
Construct from fields only (no header access).
bool has_column(const std::string &column_name) const
Check if column exists.
CsvRow(Array< std::string > fields, const Array< std::string > &header)
Construct with header reference for name-based access.
const std::string & operator[](size_t index) const
Get field by index.
const Array< std::string > & fields() const
Get underlying array.
T & append(const T &item)
Append a new item by copy.
size_t size() const noexcept
Count the number of elements of the list.
Main namespace for Aleph-w library functions.
long csv_to_number< long >(const std::string &field)
size_t csv_find_row(const Array< Array< std::string > > &rows, Pred predicate)
Find first row matching a predicate.
Array< Array< std::string > > csv_sort_by_column_numeric(const Array< Array< std::string > > &rows, size_t col_index, bool ascending=true)
Sort CSV data by a column with numeric comparison.
Array< Array< std::string > > csv_trim_fields(const Array< Array< std::string > > &rows)
Trim whitespace from all fields.
std::string csv_escape(const std::string &field, char delimiter=',')
Escape a string for CSV output.
Array< Array< std::string > > csv_read_file(const std::string &filename, char delimiter=',')
Read all rows from a CSV file.
Array< Array< std::string > > csv_transform(const Array< Array< std::string > > &rows, Func func)
Apply a transformation to each field.
Array< Array< std::string > > csv_filter_by_value(const Array< Array< std::string > > &rows, size_t col_index, const std::string &value)
Filter CSV rows by column value.
size_t size(Node *root) noexcept
bool csv_skip_bom(std::istream &in)
Skip UTF-8 BOM if present.
Array< Array< std::string > > csv_transpose(const Array< Array< std::string > > &rows)
Transpose CSV data (swap rows and columns).
T csv_to_number(const std::string &field)
Convert a CSV field to a numeric type.
Array< Array< std::string > > csv_rename_column(const Array< Array< std::string > > &rows, const std::string &old_name, const std::string &new_name)
Rename a column (in the header row).
Array< Array< std::string > > csv_take_rows(const Array< Array< std::string > > &rows, size_t n)
Take only the first N rows of CSV data.
std::decay_t< typename HeadC::Item_Type > T
Array< std::string > csv_get_column(const Array< Array< std::string > > &rows, size_t col_index)
Get a column from CSV data.
Array< Array< std::string > > csv_join_horizontal(const Array< Array< std::string > > &left, const Array< Array< std::string > > &right)
Join two CSV datasets horizontally (add columns).
Array< Array< std::string > > csv_unique(const Array< Array< std::string > > &rows)
Remove duplicate rows.
Array< Array< Array< std::string > > > csv_group_by(const Array< Array< std::string > > &rows, size_t col_index)
Group rows by a column value.
float csv_to_number< float >(const std::string &field)
void csv_write_row(std::ostream &out, const Array< std::string > &row, char delimiter=',', const std::string &line_ending="\n")
Write a CSV row to an output stream.
size_t csv_num_columns(const Array< std::string > &row)
Get the number of columns in a CSV row.
size_t csv_count_empty(const Array< Array< std::string > > &rows)
Count empty fields in CSV data.
std::string trim(const std::string &s)
Return a trimmed copy of a std::string (leading + trailing whitespace removed).
Array< std::string > csv_read_row(std::istream &in, char delimiter=',')
Read a single CSV row from an input stream.
size_t csv_find_by_value(const Array< Array< std::string > > &rows, size_t col_index, const std::string &value)
Find row where column equals value.
bool csv_is_rectangular(const Array< Array< std::string > > &rows)
Check if all rows have the same number of columns.
bool equal(Itor1 beg, const Itor1 &end, Itor2 cmpBeg, BinaryPredicate op=BinaryPredicate())
Test if two ranges are equal.
Array< std::string > csv_distinct(const Array< Array< std::string > > &rows, size_t col_index)
Get distinct values in a column.
Array< Array< std::string > > csv_filter(const Array< Array< std::string > > &rows, Pred predicate)
Filter CSV rows by a predicate.
Array< Array< std::string > > csv_read_all(std::istream &in, char delimiter=',')
Read all rows from a CSV input stream.
int csv_to_number< int >(const std::string &field)
double csv_to_number< double >(const std::string &field)
Array< Array< std::string > > csv_inner_join(const Array< Array< std::string > > &left, size_t left_key_col, const Array< Array< std::string > > &right, size_t right_key_col)
Inner join two CSV datasets by a key column.
void csv_write_file(const std::string &filename, const Array< Array< std::string > > &rows, char delimiter=',', const std::string &line_ending="\n")
Write CSV data to a file.
Array< Array< std::string > > csv_skip_rows(const Array< Array< std::string > > &rows, size_t n)
Skip the first N rows of CSV data.
Array< Array< std::string > > csv_select_columns(const Array< Array< std::string > > &rows, const Array< size_t > &col_indices)
Select specific columns from CSV data.
Array< Array< std::string > > csv_fill_empty(const Array< Array< std::string > > &rows, const std::string &default_value)
Replace empty fields with a default value.
size_t csv_count_if(const Array< Array< std::string > > &rows, Pred predicate)
Count rows matching a predicate.
Array< Array< std::string > > csv_join_vertical(const Array< Array< std::string > > &top, const Array< Array< std::string > > &bottom)
Join two CSV datasets vertically (add rows).
Array< Array< std::string > > csv_add_column(const Array< Array< std::string > > &rows, Func func)
Add a new column with computed values.
Array< Array< std::string > > csv_sort_by_column(const Array< Array< std::string > > &rows, size_t col_index, bool ascending=true)
Sort CSV data by a column.
void csv_write_all(std::ostream &out, const Array< Array< std::string > > &rows, char delimiter=',', const std::string &line_ending="\n")
Write multiple CSV rows to an output stream.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
size_t csv_count_rows(const Array< Array< std::string > > &rows)
Count total number of rows.
Dynamic array container with automatic resizing.