autoMap static method
TCsvHeaderMapping
autoMap({
- required List<
TCsvColumn> expectedColumns, - required List<
String> csvHeaders,
Automatically generates mapping between expected columns and CSV headers.
Implementation
static TCsvHeaderMapping autoMap({
required List<TCsvColumn> expectedColumns,
required List<String> csvHeaders,
}) {
final result = <String, String?>{};
final usedHeaders = <String>{};
// 1. Exact match (case-insensitive)
for (final col in expectedColumns) {
final match = csvHeaders.firstWhere(
(h) => !usedHeaders.contains(h) && (h.trim().toLowerCase() == col.header.trim().toLowerCase() || h.trim().toLowerCase() == col.key.trim().toLowerCase()),
orElse: () => '',
);
if (match.isNotEmpty) {
result[col.key] = match;
usedHeaders.add(match);
}
}
// 2. Normalized match (strip underscores, spaces, hyphens)
for (final col in expectedColumns) {
if (result[col.key] != null) continue;
final normalizedColHeader = _normalize(col.header);
final normalizedColKey = _normalize(col.key);
final match = csvHeaders.firstWhere(
(h) {
if (usedHeaders.contains(h)) return false;
final normalizedH = _normalize(h);
return normalizedH == normalizedColHeader || normalizedH == normalizedColKey;
},
orElse: () => '',
);
if (match.isNotEmpty) {
result[col.key] = match;
usedHeaders.add(match);
}
}
// 3. Alias / Synonym match
for (final col in expectedColumns) {
if (result[col.key] != null) continue;
for (final alias in col.aliases) {
final normalizedAlias = _normalize(alias);
final match = csvHeaders.firstWhere(
(h) => !usedHeaders.contains(h) && (_normalize(h) == normalizedAlias || h.trim().toLowerCase().contains(alias.trim().toLowerCase())),
orElse: () => '',
);
if (match.isNotEmpty) {
result[col.key] = match;
usedHeaders.add(match);
break;
}
}
}
// 4. Set remaining unmapped columns to null
for (final col in expectedColumns) {
result.putIfAbsent(col.key, () => null);
}
return TCsvHeaderMapping(result);
}