Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在CSV解析后根据特定规则逐行连接字符串_Java_Arrays_Csv_Parsing_Univocity - Fatal编程技术网

Java 如何在CSV解析后根据特定规则逐行连接字符串

Java 如何在CSV解析后根据特定规则逐行连接字符串,java,arrays,csv,parsing,univocity,Java,Arrays,Csv,Parsing,Univocity,我正在使用univocity解析器阅读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 t

我正在使用univocity解析器阅读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"));
List allRows=parser.parseAll(新文件阅读器(“E:/test.csv”);
在基于第二列唯一性进行解析和连接之后,如何逐个比较行

O/p

就3189项纪录而言— 字符串x=
在此日期2016-03-15-17.03.06.000000有效,此日期为2015-04-21-11.04.11.000000

3190条记录
字符串x=
它发生在2016-04-22-09.04.27.000000这一天,而在2016-04-23-09.04.46.000000这一天不活动

这是一个示例,您必须更加小心可能发生的异常,因此您可以这样做:

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());
}

hashcode和equals仅比较id。

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

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.
                    }
                }
            }

我希望我没有弄错你的要求。只需使用映射来存储“键”值,当您找到一个预先存在的值时,将字符串连接起来:

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]);
    }
}

希望它有帮助

我可以想出一些肮脏的方法(不是一个好的设计!):您可以为
活动
非活动
值创建两个不同的列表,并根据
id
对它们进行比较(即在本例中为3189或3190)。如果比较匹配,则连接字符串值。感谢您的回复。第一列是动态的,它可以是除活动或非活动之外的任何字符串。我们必须决定第二列而不是第一列的值。谢谢你的回复。第一列是动态的,它可以是除活动或非活动之外的任何字符串。我们必须对第二列而不是第一列的值作出决定。更新问题以消除任何混淆。没有混淆!您可以根据需要编辑发布的代码。
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
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