2

I need to convert a CSV file to a Map<String, String> and I'm using this package for the task. The problem is that the output of the map is returning a space before every key, as you can see:

{ 001: Visto de Trabalho,  002: Carta de Pesados,  003: Medicina do Trabalho,  004: Título de Residente]}

This is my code:

HashMap _refHashMap;

Future<HashMap> convertCSV() async {
  _refHashMap = await CSV_HashMap().hashMapConvertor(
      refList: ["id", "name"], csvPath: 'assets/document_types.csv');

  return _refHashMap;
}

Map<String, String> loadDocTypes() {
  convertCSV();

  var ids = _refHashMap["id"];
  var names = _refHashMap["name"];

  var map = Map.fromIterables(ids, names);

  var convertedMap = Map<String, String>.from(map);

  return convertedMap;
}

Can you help me? Thank you in advance

2
  • What is the result if you print a value? (map['key']) Commented Aug 31, 2021 at 17:01
  • Please attach the source code of the CSV data file. Commented Feb 13, 2022 at 7:11

3 Answers 3

3

Give this a try, it trims the keys to remove the whitespace at the end.

Map<String, String> loadDocTypes() {
  convertCSV();

  var ids = _refHashMap["id"];
  var names = _refHashMap["name"];

  var map = Map.fromIterables(ids, names);

  var convertedMap = Map<String, String>.from(map);

  return convertedMap.map((key, value) => MapEntry(key.trim(), value)); // Add this line
}
Sign up to request clarification or add additional context in comments.

Comments

0

It can be done in such a simple way.
Not very elegant, but this will work as long as the CSV file is as expected by this algorithm (header and records).

import 'package:fast_csv/fast_csv.dart' as _fast_csv;

void main(List<String> args) {
  final data = _fast_csv.parse(_source);
  final keys = data.first;
  final list = data.skip(1).map((e) => Map.fromIterables(keys, e)).toList();
  print(list.first);
  print(list[1]['Name']);
}

const _source = '''
Name,Total Cores,Processor Base Frequency
"Intel® Celeron® Processor G530 2M Cache, 2.40 GHz",2,2.40 GHz
"Intel® Core™ i5-3470 Processor 6M Cache, up to 3.60 GHz",4,3.20 GHz
"Intel® Core™ i3-10100F Processor 6M Cache, up to 4.30 GHz",4,3.60 GHz
''';

Output:

{Name: Intel® Celeron® Processor G530 2M Cache, 2.40 GHz, Total Cores: 2, Processor Base Frequency: 2.40 GHz} Intel® Core™ i5-3470 Processor 6M Cache, up to 3.60 GHz

Comments

0

import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:csv/csv.dart';
import 'dart:html' as html;
import '../utils/csv_helper.dart';
import '../widgets/custom_box.dart';
import '../widgets/primary_key_mapping.dart';
import '../widgets/filter_widget.dart';
import 'merge_screen.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  List<List<dynamic>> csvData1 = [];
  List<List<dynamic>> csvData2 = [];
  List<String> fields1 = [];
  List<String> fields2 = [];
  List<bool> selectedFields1 = [];
  List<bool> selectedFields2 = [];
  String? selectedPrimaryKey1;
  String? selectedPrimaryKey2;
  Map<String, String> filters = {};

  Future<void> pickCSVFile(int fileNumber) async {
    final result = await FilePicker.platform.pickFiles(type: FileType.custom, allowedExtensions: ['csv']);
    if (result != null) {
      final inputFile = result.files.single.bytes;
      List<List<dynamic>> rows = await CsvHelper().getCSVData(inputFile!);
      setState(() {
        if (fileNumber == 1) {
          csvData1 = rows;
          fields1 = rows[0].map((field) => field.toString()).toList();
          selectedFields1 = List.filled(fields1.length, false);
        } else {
          csvData2 = rows;
          fields2 = rows[0].map((field) => field.toString()).toList();
          selectedFields2 = List.filled(fields2.length, false);
        }
      });
    }
  }

  void mergeCSV() {
    List<List<dynamic>> mergedData = CsvHelper().mergeSelectedCSV(
      csvData1,
      csvData2,
      fields1,
      fields2,
      selectedFields1,
      selectedFields2,
      selectedPrimaryKey1,
      selectedPrimaryKey2,
      filters,
    );

    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => MergeScreen(mergedData: mergedData)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('CSV Merger')),
      body: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Column(
            children: [
              CustomBox(
                title: "Master CSV File",
                onTap: () => pickCSVFile(1),
                fields: fields1,
                selectedFields: selectedFields1,
                onSelectionChanged: (index, value) {
                  setState(() => selectedFields1[index] = value);
                },
              ),
              CustomBox(
                title: "Source CSV File",
                onTap: () => pickCSVFile(2),
                fields: fields2,
                selectedFields: selectedFields2,
                onSelectionChanged: (index, value) {
                  setState(() => selectedFields2[index] = value);
                },
              ),
              PrimaryKeyMapping(
                fields1: fields1,
                fields2: fields2,
                onPrimaryKeySelected: (key1, key2) {
                  setState(() {
                    selectedPrimaryKey1 = key1;
                    selectedPrimaryKey2 = key2;
                  });
                },
              ),
              FilterWidget(
                fields1: fields1,
                fields2: fields2,
                onFilterApplied: (updatedFilters) {
                  setState(() {
                    filters = updatedFilters;
                  });
                },
              ),
            ],
          ),
          Column(
            children: [
              ElevatedButton(
                onPressed: mergeCSV,
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  elevation: 5,
                  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
                  padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
                ),
                child: Text("Merge CSV Files", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

import 'package:flutter/material.dart';

class PrimaryKeyMapping extends StatefulWidget {
  final List<String> fields1;
  final List<String> fields2;
  final Function(String?, String?) onPrimaryKeySelected;

  PrimaryKeyMapping({required this.fields1, required this.fields2, required this.onPrimaryKeySelected});

  @override
  _PrimaryKeyMappingState createState() => _PrimaryKeyMappingState();
}

class _PrimaryKeyMappingState extends State<PrimaryKeyMapping> {
  String? selectedKey1;
  String? selectedKey2;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text("Map Primary Key", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            DropdownButton<String>(
              hint: Text("Select Master CSV Key"),
              value: selectedKey1,
              items: widget.fields1.map((field) => DropdownMenuItem(value: field, child: Text(field))).toList(),
              onChanged: (value) {
                setState(() {
                  selectedKey1 = value;
                  widget.onPrimaryKeySelected(selectedKey1, selectedKey2);
                });
              },
            ),
            SizedBox(width: 20),
            DropdownButton<String>(
              hint: Text("Select Source CSV Key"),
              value: selectedKey2,
              items: widget.fields2.map((field) => DropdownMenuItem(value: field, child: Text(field))).toList(),
              onChanged: (value) {
                setState(() {
                  selectedKey2 = value;
                  widget.onPrimaryKeySelected(selectedKey1, selectedKey2);
                });
              },
            ),
          ],
        ),
      ],
    );
  }
}

import 'package:flutter/material.dart';

class FilterWidget extends StatefulWidget {
  final List<String> fields1;
  final List<String> fields2;
  final Function(Map<String, String>) onFilterApplied;

  FilterWidget({required this.fields1, required this.fields2, required this.onFilterApplied});

  @override
  _FilterWidgetState createState() => _FilterWidgetState();
}

class _FilterWidgetState extends State<FilterWidget> {
  Map<String, TextEditingController> controllers = {};

  @override
  void initState() {
    super.initState();
    for (var field in widget.fields1 + widget.fields2) {
      controllers[field] = TextEditingController();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text("Apply Filters", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
        ...controllers.keys.map((field) {
          return Padding(
            padding: const EdgeInsets.symmetric(vertical: 5),
            child: TextField(
              controller: controllers[field],
              decoration: InputDecoration(
                labelText: "Filter for $field",
                border: OutlineInputBorder(),
              ),
              onChanged: (value) {
                widget.onFilterApplied({field: value});
              },
            ),
          );
        }).toList(),
      ],
    );
  }
}

<!-- begin snippet: js hide: false console: true babel: false babelPresetReact: false babelPresetTS: false -->

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.