Split ze spacją

0

Witam mam oto taki kodzik:
https://pastebin.com/GsQjEFyn

Sprawa wygląda tak, że liczy on sobie średnią z kolumny podaną do tablicy values i w zależności jaki index podamy to wylicza z danej kolumny, dla przykłady values[0] wylicza 1 kolumne z pliku zewnętrzego .csv. W pliku csv mam takie oto wartości.

10.12345 134.12345 5.12345 134.12345 5.12345
195.12345 36.12345 134.12345 5.12345 134.12345
134.12345 5.12345 134.12345 5.12345 134.12345

W momencie ustawienia w kodzie split(",") oraz w pliku csv separatora przecinka normalnie neutralizuje wszystkie inne wartości poza 1 kolumną od lewej. Problem w tym, że potrzebuje mieć spację i split(" ") ani split("\s") nie działają i wyrzuca mi wszystkie wartości dostępne w pliku z których liczy średnią jako wszystkie dane. Ktoś miał taki problem i wie jak go rozwiązać?

2

Możesz wczytać je do listy list (jedna na wiersz) i potem odpowiednio odfiltrować. Coś na zasadzie:

        int index = 2;
        double average = Arrays.stream(text.split("\n"))
                .map(line -> line.split(" "))
                .map(line -> line[index])
                .mapToInt(Integer::parseInt)
                .summaryStatistics()
                .getAverage();
2

dla takiego csv:

10.12345, 134.12345, 5.12345, 134.12345, 5.12345
195.12345, 36.12345, 134.12345, 5.12345, 134.12345
134.12345, 5.12345, 134.12345, 5.12345, 134.12345

rozwiązanie:

public class AppT {
	public static void main(String... args) throws IOException {
		int idx = 0;
		String csvFilePathName = "test.csv";
		double avg = Files.readAllLines(Paths.get(csvFilePathName)).stream()
				.map(x -> x.split(","))
				.map(x -> x[idx])
				.mapToDouble(Double::parseDouble)
				.average()
				.getAsDouble();
		System.out.println(avg);
	}
}

1

Poniżej masz wersję "po studencku"
Kod dla tej samej wersji pliku co Julian.

public class Paprotka {

	public static void main(String[] args) throws IOException {
		String fileName = "data.csv";
		Path raportPath = Paths.get(fileName);
		List<String> lines = Files.readAllLines(raportPath);

		double sum = sumValuesByColumnIndex(lines, 0);
		double result = sum / lines.size(); // -1 gdy pierwsza linia to naglowki, jesli nie to samo lines.size()
		System.out.print(sum);
		System.out.print(result);

	}

	public static double sumValuesByColumnIndex(List<String> lines, int index) {
		double sum = 0;
		for (String line : lines) {
			String[] splittedValues = line.split(" ");
			sum += Double.parseDouble(splittedValues[index]);
		}

		return sum;
	}

}

Natomiast lepiej by było to zrobić streamami, tak jak masz rozwiązania powyżej. Na sam początek przygody z Java, wersja studencka jest ok, ale kiedyś i tak będziesz musiał nauczyć się wykorzystywać streamy i wyrażenia lambda.

0

Jak wymnożyć jakąś zmienną powiedzmy x = 10 razy każdy element w kolumnie, mając ten kod?

double avg1 = Files.readAllLines(Paths.get(csvFilePathName)).stream()
.skip(1)
.map(x -> x.split(" "))
.map(x -> x[idx])
.mapToDouble(Double::parseDouble)
.reduce(0,(l1,l2) -> l1*l2);

W tej sytuacji mnoży każdy element razy inny w kolumnie, a nie do końca o to mi chodzi

0
Jan_Programista82 napisał(a):

Jak wymnożyć jakąś zmienną powiedzmy x = 10 razy każdy element w kolumnie, mając ten kod?

double avg1 = Files.readAllLines(Paths.get(csvFilePathName)).stream()
.skip(1)
.map(x -> x.split(" "))
.map(x -> x[idx])
.mapToDouble(Double::parseDouble)
.reduce(0,(l1,l2) -> l1*l2);

W tej sytuacji mnoży każdy element razy inny w kolumnie, a nie do końca o to mi chodzi

Files.readAllLines(Paths.get(csvFilePathName)).stream()
				.map(x -> x.split(" "))
				.map(x -> x[idx])
				.mapToDouble(Double::parseDouble)
				.map(x -> x*10)
				.average()
				.getAsDouble();

5 linijka

0

Mam dwie wartości w wierszu w pliku csv oddzielone spacją. Jak można wymnożyć te dwie wartości oraz dodać wartość mnożenia z linii pod spodem? Podaję przykład dla uproszczenia:
line 1 : a b
line 2 : c d
Ma działać tak: (ab) + (cd) I w zasadzie tak do skutku dodawać iloczyn z linii poniżej, aż nie wyczerpią się wszystkie wiersze w pliku. Ktoś, coś, jakieś pomysły?

1
  double calculate(String csvFilePathName) throws IOException {
    return Files.readAllLines(Paths.get(csvFilePathName))
        .stream() // wczytujemy plik, linijka po linijce
        .map(line -> line.split(" ")) // linijkę transformujemy na tablicę obiektów String poprzez podział linii na łańcuchy znaków oddzielone spacją
        .map(this::multiplyLine) // zmapowanie każdej linii do iloczynu jej wartości - wywołanie metody multiplyLine(String[]) dla każdej linii
        .filter(OptionalDouble::isPresent) // filtrujemy te, które mają wartość (tj. linijka nie była pusta)
        .mapToDouble(OptionalDouble::getAsDouble) // mapujemy obiekty OptionalDouble do obiektów Double - operujemy obecnie na Streamie z obiektami przechowującymi
                                                  // iloczyn wartości z poszcególnych linii
        .sum(); // sumujemy iloczyny uzyskane ze wszystkich linii
  }

  private OptionalDouble multiplyLine(String[] line) {
    return Arrays.stream(line) // tworzymy Stream na podstawie tablicy obiketów String
        .filter(s -> !s.isBlank()) // odfiltrowanie łańcuchów znaków - pustych bądź składających się z tylko z białych znaków
        .mapToDouble(Double::parseDouble) // parsujemy każdy String do obiektu Double
        .reduce((a, b) -> a* b); // redukujemy Stream Double do jednego OptionalDouble (jeśli linia jest pusta, to OptionalDouble też będzie pusty)
                                 // podając funkcję, która ma się wykonać no kolejnych obiektach - tutaj mnożenie każdych dwóch kolejnych obiektów
  }

Generalnie, odnoszę wrażenie, że nie do końca wiesz, co w zasadzie robisz i co dzieje się w kodzie, który w tym wątku był wrzucany.
W kontekście Streamów, polecam zajrzeć na początek tutaj: https://www.baeldung.com/java-8-streams

1 użytkowników online, w tym zalogowanych: 0, gości: 1