commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Luc Maisonobe <Luc.Maison...@free.fr>
Subject Re: [csv] Headers
Date Tue, 13 Mar 2012 07:32:40 GMT
Le 13/03/2012 00:56, sebb a écrit :
> On 12 March 2012 22:11, Emmanuel Bourg <ebourg@apache.org> wrote:
>> [csv] is missing some elements to ease the use of headers. I have no clear
>> idea on how to address this, here are my thoughts.
>>
>> Headers are used when the fields are accessed by the column name rather than
>> by the index. This provides some flexibility because the input file can be
>> slightly modified by reordering the columns or by inserting new columns
>> without breaking the existing code.
>>
>> Using the current API here is how one would work with headers:
>>
>>  CSVParser parser = new CSVParser(in);
>>  Iterator<String[]> it = parser.iterator();
>>
>>  // read the header
>>  String[] header = it.next();
>>
>>  // build a name to index mapping
>>  Map<String, Integer> mapping = new HashMap<>();
>>  for (int i = 0; i < header.length; i++) {
>>      mapping.put(header[i], i);
>>  }
>>
>>  // parse the records
>>  for (String[] record : parser) {
>>      Person person = new Person();
>>      person.setName(record[mapping.get("name")]);
>>      person.setEmail(record[mapping.get("email")]);
>>      person.setPhone(record[mapping.get("phone")]);
>>      persons.add(person);
>>  }
>>
>> The user has to take care of the mapping, which is not very friendly. I have
>> several solutions in mind:
>>
>> 1. Do nothing and address it in the next release with the bean mapping.
>> Parsing the file would then look like this:
>>
>>  CSVFormat<Person> format = CSVFormat.DEFAULT.withType(Person.class);
>>  for (Person person : format.parse(in)) {
>>      persons.add(person);
>>  }
>>
> 
> Does this automatically mean that the file has a header?
> Or is there another way to link columns to Person attributes?
> 
> I don't think this should be the only way of handling named columns;
> it's not always convenient to create a type.

I agree. Sometimes, the colums are just a part of a class that would
need other parameters not in the columns (but perhaps in a custom
comment of the header, if these parameters are constant throughout the
file. So providing intermediate level API (with mapping already done,
but still access to individual fields) is a must.

> 
>> 2. Add a parser returning a Map instead of a String[]
>>
>>  // declare the header in the format,
>>  // the header line will be parsed automatically
>>  CSVFormat format = CSVFormat.DEFAULT.withHeader();
>>
>>  for (Map<String, String> record : new CSVMapParser(in, format))) {
>>      Person person = new Person();
>>      person.setName(record.get("name"));
>>      person.setEmail(record.get("email"));
>>      person.setPhone(record.get("phone"));
>>      persons.add(person);
>>  }
> 
> That seems OK; one can also just use the column values directly.

+1


Luc

> 
>>
>> 2bis. Have the same CSVParser class returning String[] or Map<String,
>> String> depending on a generic parameter. Not sure it's possible with type
>> erasure.
>>
> 
> It's not possible for two methods to differ only by return parameter
> type, so this can only be done if the method parameters are different
> after type erasure.
> 
>> 3. Have the parser maintain the name->index mapping. The parser read the
>> first line automatically if the format declares a header, and a
>> getColumnIndex() method is exposed.
>>
>>  CSVFormat format = CSVFormat.DEFAULT.withHeader();
>>  CSVParser parser = new CSVParser(in, format);
>>
>>  // parse the records
>>  for (String[] record : parser) {
>>      Person person = new Person();
>>      person.setName(record[parser.getColumnIndex("name")]);
>>      person.setEmail(record[parser.getColumnIndex("email")]);
>>      person.setPhone(record[parser.getColumnIndex("phone")]);
>>      persons.add(person);
>>  }
> 
> Quite awkard to use.
> 
>>
>> What do you think?
>>
>> Emmanuel Bourg
>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message