我正在使用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
答案 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