Skip to content

List Converter — C++ source

Transform a list between separators (newline, comma, space, pipe, semicolon, tab) with trim, dedupe, sort, and empty-removal options. Runs entirely in your browser, with a shareable link.

This is the C++ implementation — the same logic the interactive tool runs, in a shareable, citable form.

// List Converter — split/trim/dedup/sort/join between separators — C++ (C++20) port of the list-converter tool.

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>

namespace list_converter {

// Resolve a TS-style separator name to its glue; unknown names pass through
// as a literal separator (the TS resolveSep behavior).
inline std::string resolve_sep(const std::string& name) {
    if (name == "newline") return "\n";
    if (name == "comma") return ",";
    if (name == "space") return " ";
    if (name == "pipe") return "|";
    if (name == "semicolon") return ";";
    if (name == "tab") return "\t";
    return name;
}

struct Options { // defaults match the TS ListOptions (newline -> comma)
    std::string from = "newline", to = "comma";
    bool trim = false, remove_empty = false, unique = false;
    bool sort = false, case_insensitive = false;
};

inline std::vector<std::string> split(const std::string& s, const std::string& sep) {
    std::vector<std::string> out;
    if (sep.empty()) { out.push_back(s); return out; }
    size_t start = 0;
    while (true) { // mirrors Go strings.Split: trailing empties survive
        size_t hit = s.find(sep, start);
        if (hit == std::string::npos) { out.push_back(s.substr(start)); return out; }
        out.push_back(s.substr(start, hit - start));
        start = hit + sep.size();
    }
}

inline std::string lower(std::string s) {
    std::transform(s.begin(), s.end(), s.begin(),
                   [](unsigned char c) { return std::tolower(c); });
    return s;
}

// Convert a list between separators: split -> (trim) -> (drop empties) ->
// (dedup, first occurrence wins) -> (stable sort) -> join. Mirrors the Go twin.
inline std::string convert(const std::string& input, const Options& o = {}) {
    std::vector<std::string> items = split(input, resolve_sep(o.from));
    const std::string to = resolve_sep(o.to);

    if (o.trim)
        for (auto& s : items) {
            const auto b = s.find_first_not_of(" \t\r\n");
            if (b == std::string::npos) { s.clear(); continue; }
            s.erase(s.find_last_not_of(" \t\r\n") + 1).erase(0, b);
        }
    if (o.remove_empty) items.erase(std::remove_if(items.begin(), items.end(),
                                     [](const std::string& s) { return s.empty(); }),
                                    items.end());
    if (o.unique) { // the set holds keys only; items keep their casing
        std::unordered_set<std::string> seen;
        items.erase(std::remove_if(items.begin(), items.end(),
                                   [&](const std::string& s) {
                                       return !seen.insert(o.case_insensitive ? lower(s) : s).second;
                                   }),
                    items.end());
    }
    if (o.sort) // std::stable_sort: equal keys keep their input order
        std::stable_sort(items.begin(), items.end(),
                         [&](const std::string& a, const std::string& b) {
                             return o.case_insensitive ? lower(a) < lower(b) : a < b;
                         });
    std::string out;
    for (size_t i = 0; i < items.size(); i++) {
        if (i != 0) out += to;
        out += items[i];
    }
    return out;
}

} // namespace list_converter

int main() {
    using namespace list_converter;
    Options o;
    o.trim = o.remove_empty = o.unique = o.sort = o.case_insensitive = true;
    std::cout << convert("b\n a \nB\na\n\nc", o) << "\n"; // a,b,c
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →