Как проанализировать столбец из строки CSV с помощью jackson CsvMapper или другого анализатора csv?

У меня есть метод Java, который получает строку значений CSV и целочисленный индекс для ссылки на столбец в строке CSV для анализа. Метод возвращает значение, связанное с целочисленным индексом в строке CSV.

Например, если у меня есть строка CSV с заголовком и вторая строка со значениями, определенными как:

String csvString = "Entry #,Date Created,Date Updated, IP Address
                    165,8/22/13 14:46,,11.222.33.444";

и целочисленный индекс, полученный методом, был равен 1, я ожидаю, что метод вернет строку "165"

И если целочисленный индекс, полученный методом, равен 2, я ожидаю, что метод вернет строку «8/22/13 14:46».

так далее,...

Я не хочу просто разбивать строку CSV запятыми, так как это может выглядеть некрасиво, и я уверен, что есть парсер CSV, который уже выполняет подобный синтаксический анализ. Судя по моим поискам в Google, OpenCSV или Jackson CsvMapper могут это сделать.

Я играл с библиотекой com.fasterxml.jackson.dataformat.csv.CsvMapper, чтобы проанализировать соответствующий столбец этой строки CSV, и вот что у меня есть:

int csvFieldIndex (this is the integer index passed into my method)

String csvString = "Entry #,Date Created,Date Updated, IP Address
                    165,8/22/13 14:46,,11.222.33.444";

CsvSchema csvSchema = CsvSchema.emptySchema().withHeader();
ObjectReader mapper = new CsvMapper().reader(Map.class).with(csvSchema);

MappingIterator<Map<String, Object>> iter = null;
iter = mapper.readValues(csvString);

while (iter.hasNext()) {
    Map<String, Object> row = iter.next();

    System.out.Println("row= " + row.toString());
}

Но этот итератор дает мне все значения csv, а это не то, что я хочу; Мне просто нужно одно значение, связанное с моим целочисленным индексом.

Вот что я получаю, когда запускаю этот фрагмент кода:

row= {Entry #=165, Date Created=8/22/13 14:46, Date Updated=, IP Address=11.222.33.444}

Есть ли способ использовать Jackson CsvMapper для этого?

======== ОБНОВЛЕНИЕ: ========

Основываясь на отзывах от keshlam, я смог разобрать столбец из CSV с помощью следующего кода:

CsvSchema csvSchema = CsvSchema.emptySchema().withHeader();
ObjectReader mapper = new CsvMapper().reader(Map.class).with(csvSchema);
MappingIterator<Map<String, Object>> iter = null;
iter = mapper.readValues(csvString);

// iterate over whole csv and store in a map
Map<String, Object> row = null;
while (iter.hasNext()) {
    row = iter.next();
}

// now put the set of field names (keys) from this map into an array
String[] csvKeysArray = row.keySet().toArray(new String[0]);

int j = 0;
// loop over this array of keys and compare with csvFieldIndex
for (int i = 0; i < csvKeysArray.length; i++) {
     // increment j by 1 since array index starts at 0 but input index starts at 1
     j = i + 1;

     if (j == csvFieldIndex) {
        csvValue = row.get(csvKeysArray[i]).toString();
     }
}

return csvValue;

person erj2code    schedule 08.01.2014    source источник
comment
Класс com.fasterxml.jackson.dataformat.csv.CsvMapper фактически используется для генерации JSON из CSV. Я думаю, что это не ваше требование, поэтому вам лучше использовать OpenCSV.   -  person shazin    schedule 09.01.2014
comment
У вас есть пример того, как это сделать с OpenCSV?   -  person erj2code    schedule 09.01.2014
comment
Я получил ответ на свой запрос от этого вопроса. :D Спасибо @erj2code   -  person Sanjay Singh Rawat    schedule 11.11.2016


Ответы (1)


Если я следую тому, что вы просите, и правильно понимаю ваш код (я никогда не использовал этот CsvMapper), измените последний цикл на

 while (iter.hasNext()) {
    Map<String, Object> row = iter.next();
    System.out.Println("Entry #= " + row.get("Entry #");
  }

Если вы хотите получить доступ к столбцам численно, а не по имени (почему?), настройте сопоставление числа с именем столбца и используйте его для получения ключа, который вы передаете операции get().

person keshlam    schedule 09.01.2014
comment
В этот метод будет отправлено несколько разных строк CSV с разными именами полей. Поэтому вместо того, чтобы выяснять все имена полей (что меня в любом случае не волнует), я решил, что проще использовать число, чтобы определить, какой столбец строки CSV нужно вернуть. - person erj2code; 09.01.2014
comment
Кроме того, некоторые из строк CSV, которые будет анализировать этот метод, могут иметь более 100 столбцов. - person erj2code; 09.01.2014
comment
Спасибо за ваш отзыв. Я добавил свое решение выше под заголовком ======== ОБНОВЛЕНИЕ: ======== - person erj2code; 10.01.2014