如何在CSV解析后基于某些规则连接字符串 - 逐行

时间:2017-09-27 11:02:54

标签: java arrays csv parsing univocity

我正在使用univocity解析器 - https://www.univocity.com/pages/parsers-tutorial阅读CSV列表。以下是test.csv的外观

Active;3189;Active on this date 2015-03-15-17.03.06.000000

Catalog;3189;This is for date 2015-04-21-11.04.11.000000

Master;3190;It happens on this date 2016-04-22-09.04.27.000000

InActive;3190;Inactive on this date 2016-04-23-09.04.46.000000

下面的代码进行解析 -

List<String[]> allRows = parser.parseAll(new FileReader("E:/test.csv"));

如何根据第二列唯一性解析和连接后逐个比较行

O / P

共3189条记录 - 字符串x = Active on this date 2016-03-15-17.03.06.000000 and This is for date 2015-04-21-11.04.11.000000

共3190条记录 字符串x = It happens on this date 2016-04-22-09.04.27.000000 and Inactive on this date 2016-04-23-09.04.46.000000

3 个答案:

答案 0 :(得分:2)

这是一个例子,你必须更加小心可能发生例外,所以你可以做这样的事情:

String pattern = "^(Active|Inactive);([^;]*);(.*)$";
Pattern r = Pattern.compile(pattern);
for (String[] row : allRows) {
    if (row[0].matches(pattern)) {
        Matcher m = r.matcher(row[0]);
        if (m.find()) {
            Record record = records.get(m.group(2)) == null ? new Record() : records.get(m.group(2));
            record.setId(m.group(2));
            if (m.group(1).equals("Active")) {
                record.setActiveComment(m.group(3));
            } else if (m.group(1).equals("Inactive")) {
                record.setInactiveComment(m.group(3));
            }
            records.put(record.getId(), record);
        } else {
            System.out.println("NO MATCH");
        }
    }
}

for (Entry<String, Record> rec : records.entrySet()) {
    System.out.println(rec.getValue().getActiveComment() + " and " + rec.getValue().getInactiveComment());
}

班级记录:

public class Record {

    private String id;

    private String activeComment;

    private String inactiveComment;

    //add setters getters

    //hashcode equals and toString.

}

hashcode和equals仅比较id。

答案 1 :(得分:2)

我希望我的要求合适。只需使用地图存储“键”值,当您发现预先存在的值连接字符串时:

public static void main(String... args) {
    CsvParserSettings settings = new CsvParserSettings();
    settings.getFormat().setDelimiter(';');

    //looks like you are not interested in the first column.
    //select the columns you actually need - faster and ensures all rows will come out with 2 columns
    settings.selectIndexes(1, 2);

    CsvParser parser = new CsvParser(settings);

    //linked hashmap to keep the original order if that's important
    Map<String, String[]> rows = new LinkedHashMap<String, String[]>();
    for (String[] row : parser.iterate(new File("E:/test.csv"))) {

        String key = row[0];
        String[] existing = rows.get(key);
        if (existing == null) {
            rows.put(key, row);
        } else {
            existing[1] += " and " + row[1];
        }
    }

    //print the result
    for(String[] row : rows.values()){
        System.out.println(row[0] + " - " + row[1]);
    }
}

打印出来:

3189 - Active on this date 2015-03-15-17.03.06.000000 and This is for date 2015-04-21-11.04.11.000000
3190 - It happens on this date 2016-04-22-09.04.27.000000 and Inactive on this date 2016-04-23-09.04.46.000000

希望有所帮助

答案 2 :(得分:1)

我尝试了一些以某种方式解决问题的方法。但我不确定它是否是一个好的设计。您可以尝试将以下代码添加到您的方法中:

for (int i = 0; i < allRows.size(); i++) {
                if (allRows.get(i).length < 2)
                    continue;
                for (int j = i + 1; j < allRows.size(); j++) {
                    if (allRows.get(j).length < 2)
                        continue;
                    if (allRows.get(i)[1].equals(allRows.get(j)[1])) // Comparing the second column with other objects
                    {
                        System.out.println("for " + allRows.get(i)[1] + " records- String X=" + allRows.get(i)[2] + " and " + allRows.get(j)[2]);
                        // Say if you have more than two occurences to 3189 then it prints two times this line.
                    }
                }
            }

输出:

for 3189 records- String X=Active on this date 2015-03-15-17.03.06.000000 and This is for date 2015-04-21-11.04.11.000000
for 3190 records- String X=It happens on this date 2016-04-22-09.04.27.000000 and Inactive on this date 2016-04-23-09.04.46.000000