CSV auslesen und Inhalt vergleichen

Damn

Mitglied
Hallo,
ich versuche gerade:

- zwei csv Dateien einzulesen ( A hat 2 Spalten und 1 Mio Zeilen und B 2 Spalte und 1000 Zeilen)
z.b: Nr., Artikel B) Nr., Artikel
01,Spiel|Konsole|playstation 01, Spiel
02,SpielKonsole|wii 02,playstation

- die Artikelname in A mit den Artikelnamen in B zu vergleichen
- Für jede Zeile (A) aufzuzählen, wieviel Wörter in Zeilen B vorkommen

zb.:

01,Spiel|Konsole|playstation 2 Wörter
02,SpielKonsole|wii 1 Wort


- Das Ergebnis als CSV zu speichern


Ich habe ein Standardprogramm geschrieben, aber habe mehrere Problem:

Java:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
 
public class Test 
{
	//static int zeileAnzahl= 0;
    public static void main(String[] args) throws IOException 
    {
    	BufferedReader reader = new BufferedReader(new FileReader(new File("E:/Persönlich/A.csv")));
    	//BufferedReader reader = new BufferedReader(new FileReader(new File("E:/Persönlich/B.csv")));
        String line;
        String[] temp;
        ArrayList<String[]> strings = new ArrayList<String[]>();
        while((line = reader.readLine()) != null)
        {
            strings.add(line.split(","));
           // System.out.println(strings);
            
           
        }
        

        for(int i = 0; i < strings.size(); i++) 
        {
            String[] arr = (String[]) strings.get(i);
         
            //get array of one line
            for(int j = 0; j < arr.length; j++)
            {
                
                System.out.println(arr[j]);
                //zeileAnzahl++;
            }  
        }
       // System.out.println(zeileAnzahl);
    }
}


Die großere Datei wird nicht vom Anfang eingelesen! Ich habe mit der kleineren Datei (B) versucht und die wird komplett eingelesen.

Kann jemand mir helfen
 
G

Gast2

Gast
Musst du die Datei selbst parsen oder kannst du nen fertigen CSV Parser nutzen? Dann hätte ich ne schöne kompakte Lösung auf Lager.

Falls du das selbst parsen musst dann solltest du so vorgehen:
Zuerst Datei B komplett einlesen in eine Liste.
Danach Zeile für Zeile Datei A auslesen und für jeden Eintrag zählen wieoft der String in Liste B vorkommt. Das Ergebnis schreibst du direkt nach Datei C.
 

Damn

Mitglied
Java:
Reader reader = new FileReader("A.csv"); 
    	CSVReader<String[]> csvPersonReader = CSVReaderBuilder.newDefaultReader(reader);
    	List<String[]> persons = csvPersonReader.readAll();

Ich bekomme Fehler:

CSVReaderBuilder cannot be resolved.
 
G

Gast2

Gast
Hi,
ich habe gestern schon das Wiki für die neue Version angepasst, da hat sich nen bisschen was getan. Lad dir bitte mal die Version 1.1.0 runter. Die findest du jetzt im Downloadbereich.

In der Zwischenzeit baue ich dir mal nen kleines Beispiel fertig :)
 
G

Gast2

Gast
Hab dir mal nen kleines Beispiel gebastelt. Bin mir aber nicht so sicher ob ich das Zählen der Artikel richtig verstanden habe, ich glaube du meinst da was anderes ;) Aber schaus dir mal an (es sieht komplizierter aus als es ist ^^), wenn du noch Fragen/Probleme damit hast, dann sag bescheid.

Java:
public class Main {
	public static void main(String[] args) throws IOException {
		List<Article> articles = readArticleList("/B.csv");

		// read list A and write qun
		CSVReader<Article> articleReader = buildCSVReader("/A.csv");
		CSVWriter<ArticleQuantity> articleQuantityWriter = buildCSVWriter("/C.csv");

		for (Article article : articleReader) {
			ArticleQuantity articleQuantity = countArticle(articles, article);
			articleQuantityWriter.write(articleQuantity);
			articleQuantityWriter.flush();
		}

		articleQuantityWriter.close();
		articleReader.close();
	}

	private static ArticleQuantity countArticle(List<Article> articles, Article art) {
		int count = 0;
		for (Article article : articles) {
			if (article.equals(art)) {
				count++;
			}
		}

		return new ArticleQuantity(art, count);
	}

	private static CSVWriter<ArticleQuantity> buildCSVWriter(String file) throws IOException {
		String userHome = System.getProperty("user.home");
		Writer out = new FileWriter(userHome + file);
		CSVWriter<ArticleQuantity> csvWriter = new CSVWriterBuilder<ArticleQuantity>(out)
				.strategy(CSVStrategy.UK_DEFAULT).entryConverter(new ArticleQuantityEntryConverter()).build();
		return csvWriter;
	}

	private static CSVReader<Article> buildCSVReader(String file) {
		Reader csvFile = new InputStreamReader(Main.class.getResourceAsStream(file));
		CSVReader<Article> csvArticleReader = new CSVReaderBuilder<Article>(csvFile).strategy(CSVStrategy.UK_DEFAULT)
				.entryParser(new ArticleEntryParser()).build();
		return csvArticleReader;
	}

	private static List<Article> readArticleList(String file) throws IOException {
		CSVReader<Article> csvArticleReader = buildCSVReader(file);
		List<Article> articles = csvArticleReader.readAll();
		csvArticleReader.close();

		return articles;
	}

	private static class ArticleEntryParser implements CSVEntryParser<Article> {
		@Override
		public Article parseEntry(String... data) {
			if (data.length != 2) {
				throw new IllegalArgumentException("data is not a valid article");
			}
			return new Article(data[1]);
		}
	}

	private static class ArticleQuantityEntryConverter implements CSVEntryConverter<ArticleQuantity> {
		@Override
		public String[] convertEntry(ArticleQuantity e) {
			return new String[] { e.getArticle().getName(), String.valueOf(e.getQuantity()) };
		}
	}
}
 

Damn

Mitglied
Ich habe das Projekt von EikeB benutzt und angepasst.
Leider habe ich immer noch Problem:

Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.<init>(Unknown Source)
at java.io.InputStreamReader.<init>(Unknown Source)
at de.eikeb.jcsv.demo.Main.readCategories(Main.java:70)
at de.eikeb.jcsv.demo.Main.main(Main.java:23)




CSVEntryConverter cannot be resolved to a type line 105 Java Problem
CSVEntryParser cannot be resolved to a type line 80 Java Problem
CSVEntryParser cannot be resolved to a type line 93 Java Problem

Kann jemand mit dabei helfen?

Java:
package de.eikeb.jcsv.demo;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;

import de.eikeb.jcsv.CSVStrategy;
import de.eikeb.jcsv.reader.CSVEntryParser;
import de.eikeb.jcsv.reader.CSVReader;
import de.eikeb.jcsv.reader.internal.CSVReaderBuilder;
import de.eikeb.jcsv.writer.CSVEntryConverter;
import de.eikeb.jcsv.writer.CSVWriter;
import de.eikeb.jcsv.writer.internal.CSVWriterBuilder;

public class Main {
	private static CSVStrategy strategy = new CSVStrategy(';', '"', '#', true, true);

	public static void main(String[] args) throws IOException {
		List<Category> categories = readCategories("/B.csv");

		// read list A and write quantities
		CSVReader<CategoryList> categoryListReader = buildCategoryListReader("/A.csv");
		CSVWriter<CategoryQuantity> categoryQuantityWriter = buildCSVWriter("/C.csv");

		for (CategoryList cl : categoryListReader) {
			CategoryQuantity categoryQuantity = countCategories(categories, cl);
			categoryQuantityWriter.write(categoryQuantity);
			categoryQuantityWriter.flush();

		}

		categoryQuantityWriter.close();
		categoryListReader.close();
	}

	private static CategoryQuantity countCategories(List<Category> categories, CategoryList cl) {
		int count = 0;
		for (String category : cl.getCategories()) {
			for (Category cat : categories)  {
				if (cat.getName().equalsIgnoreCase(category)) {
					count++;
					break;
				}
			}
		}

		return new CategoryQuantity(cl.getId(), count);
	}

	private static CSVWriter<CategoryQuantity> buildCSVWriter(String file) throws IOException {
		String userHome = System.getProperty("user.home");
		Writer out = new FileWriter(userHome + file);
		CSVWriter<CategoryQuantity> csvWriter = new CSVWriterBuilder<CategoryQuantity>(out).strategy(strategy)
				.entryConverter(new CategoryQuantityEntryConverter()).build();
		return csvWriter;
	}

	private static CSVReader<CategoryList> buildCategoryListReader(String file) {
		Reader csvFile = new InputStreamReader(Main.class.getResourceAsStream(file));
		CSVReader<CategoryList> csvReader = new CSVReaderBuilder<CategoryList>(csvFile).strategy(strategy)
				.entryParser(new CategoryListEntryParser()).build();
		return csvReader;
	}

	private static List<Category> readCategories(String file) throws IOException {
		Reader csvFile = new InputStreamReader(Main.class.getResourceAsStream(file));
		CSVReader<Category> csvReader = new CSVReaderBuilder<Category>(csvFile).strategy(strategy)
				.entryParser(new CategoryEntryParser()).build();

		List<Category> articles = csvReader.readAll();
		csvReader.close();

		return articles;
	}

	private static class CategoryEntryParser implements CSVEntryParser<Category> {
		@Override
		public Category parseEntry(String... data) {
			if (data.length != 2) {
				throw new IllegalArgumentException("data is not a valid article");
			}
			int id = Integer.parseInt(data[0]);
			String name = data[1];

			return new Category(id, name);
		}
	}

	private static class CategoryListEntryParser implements CSVEntryParser<CategoryList> {
		@Override
		public CategoryList parseEntry(String... data) {
			if (data.length != 2) {
				throw new IllegalArgumentException("data is not a valid article");
			}
			int id = Integer.parseInt(data[0]);
			List<String> categories = Arrays.asList(data[1].split("\\||\\s/\\s"));
			return new CategoryList(id, categories);
		}
	}

	private static class CategoryQuantityEntryConverter implements CSVEntryConverter<CategoryQuantity> {
		@Override
		public String[] convertEntry(CategoryQuantity e) {
			return new String[] { String.valueOf(e.getId()), String.valueOf(e.getQuantity()) };
		}
	}
}
 
Zuletzt bearbeitet:
G

Gast2

Gast
Wie gesagt:

Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.<init>(Unknown Source)
at java.io.InputStreamReader.<init>(Unknown Source)
at de.eikeb.jcsv.demo.Main.readCategories(Main.java:70)
at de.eikeb.jcsv.demo.Main.main(Main.java:23)
In meinem Beispiel lade ich die Dateien (der einfachheit halber) als Ressource, wenn du das auch so machen willst, dann musst du deine Dateien in nen source ordner legen. Wenn du die Dateien von deiner Festplatte laden willst dann mach das so:
Java:
Reader reader = new FileReader(derPfadZuDeinerDatei);

Java:
CSVEntryConverter cannot be resolved to a type line 105 Java Problem
CSVEntryParser cannot be resolved to a type line 80 Java Problem
CSVEntryParser cannot be resolved to a type line 93 Java Problem
Da hast du die Library falsch eingebunden, der Fehler tritt bei mir nicht auf.
 

Damn

Mitglied
Hi zusammen,


mit meinem Programm kann ich jetzt die Wörter in der A.CSV-Datei mit dem Wörtern in der B.CSV-Datei vergleichen, die aufzählen und die gleichen Wörter (als Liste) ausgeben.

z.B:Baby,|Kids| & |Teens| Spielwaren | & | Schulbedarf | Kinderfahrzeuge |Spielzeug |Autos futscher | Autos 3 [Schulbedarf, Kinderfahrzeuge, Autos]

Bis jetzt vergleiche ich die Kategorien wie:


Java:
private static CategoryQuantity countCategories(List<Category> categories, CategoryList cl) {
		int count = 0;
		List<String> cat1 = new ArrayList<String>();
		for (String category : cl.getCategories()) {
			for (Category cat : categories)  {
				if (cat.getName().equalsIgnoreCase(category)) {
					cat1.add(cat.getName());
					count++;
					break;
				}
			}
		}


Das Problem ist, dass ich nur die identischen Wärter vergleiche.
Ich möchte gern auch Teilwörter vergleichen.

Z.b: Baby (in A.csv) soll auch gelich Babyliegen (in B.csv) sein.

Also, ich möchte auch Teilwörter vergleichen.

Kann einer mir helfen?
 
G

Gast2

Gast
Da würd ich dir mal die API ans Herz legen wollen:
String (Java Platform SE 7 )

equalsIgnoreCase prüft ob die Wörter gleich sind (Groß-/Kleinschreibung wird ignoriert). Wenn du prüfen ob es sich um nen Teilwort handelt kannst du contains nutzen.
 

Damn

Mitglied
@EikeB, danke dir für deine Empfehlung in Bezug auf contains.


Ich habe meinen code erweitert, aber ich komme immer noch nicht auf das gewünschte Ergebnis.
Als Ergebnis möchte ich bekommen:

id,Kategorie,gefundene Kategorie, Anzahl
01,Textil|Sport|Sporttextilien|Kinder|Teile|Kindersportbekleidung|neutral,Textil|Sport|Sporttextilien,3|8,2


Ich habe 2 Problem.

1. ich speiche das gefundene Wort in eine Liste, aber ich will das gefundene Wort nur einmal angezeigt wird.
Gezeigt wird:
[Textil, Sport, Sport, Sport, Sport, Sport, Sport, Sport, Sport, Sporttextilien,Sporttextilien]

2. Ich möchte die Anzahl der gefundenen Wörter darstellen wie o.g.
Zurzeit zähle ich falsch, in dem ich immer addiere und in die Liste speichern.

Hat jemand eine Idee, wie ich die Probleme lösen kann?


Java:
	private static CategoryQuantity countCategories(List<Category> categories, CategoryList cl) {
			List<Integer> count = new ArrayList<Integer>();
			
			List<String> name = new ArrayList<String>();
				for (String category : cl.getCategories()) {
					int number= 0;
					for (Category cat : categories) {
						if (cat.getName().contains(category)) {
							name.add(category.toString());
							number++;
							count.add(number);



						}
					}
				}
 

Damn

Mitglied
Hi zusammen,

jetzt benutze ich ein MAP statt die beiden Liste (zuvor). Außerdem benutze ich noch ein Set zum kontrollieren.

Aber jetzt wie vergleiche ich sinnvoll die beiden Kategorien?



Java:
    private static CategoryQuantity countCategories(List<Category> categories, CategoryList cl) {        
        Map<String,Integer> result = new TreeMap<String,Integer>();        
        Set<String> control = new HashSet<String>();      
        List<String> categories1 = cl.getCategories();      
            
        for (String category : categories1) {      
                            
            if(control.contains(category))    
                continue;      
                  
            control.add(category);      
            if(categories1.contains(category))
            		{  
                result.put(category, Collections.frequency(categories1, category));     
            }            
        }        
        return new CategoryQuantity(cl.getId(), cl.getCategories(), result);  

    }
 

Damn

Mitglied
Ich habe eine neue for schleife, aber das Programm läuf und läuft, nach 50 Min. habe ich abgebrochen und die vorläufigen Ergebnise angeguckt und gesehen, dass das prrogramm nicht funktioniert.

Idee ?

Java:
private static CategoryQuantity countCategories(List<Category> categories, CategoryList cl) {          
        Map<String,Integer> result = new TreeMap<String,Integer>();          
        Set<String> control = new HashSet<String>();        
        List<String> categories1 = cl.getCategories();        
          
          
      for (Category cat : categories) {       
        for (String category : categories1) {        
            if(cat.getName().contains(category))  
            if(control.contains(category))      
                continue;        
                    
            control.add(category);        
            if(categories1.contains(category))  
                    {    
                result.put(category, Collections.frequency(categories1, category));       
            }              
        }    
      }  
          
        return new CategoryQuantity(cl.getId(), cl.getCategories(), result);    
  
    }
 

Neue Themen


Oben