2

我正在使用 Univocity 解析器阅读 CSV 列表 - https://www.univocity.com/pages/parsers-tutorial。下面是 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

4

3 回答 3

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。

于 2017-09-27T12:44:42.497 回答
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

希望能帮助到你

于 2017-09-27T22:42:25.960 回答
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
于 2017-09-27T13:58:59.430 回答