Как считать гласные в Java через функциональное программирование? - PullRequest
7 голосов
/ 31 января 2020

Мне нужно посчитать количество гласных в списке слов в Функциональном Java. Если у меня есть этот список:

List<String> l = Arrays.asList("hello", "world", "test");

Моя идея состояла в том, чтобы «удалить» гласные, а затем сделать вычитание следующим образом:

int tot = l.stream().map(s -> s.replace("a", "")).
            map(s -> s.replace("e", "")).
            map(s -> s.replace("i", "")).
            map(s -> s.replace("o", "")).
            map(s -> s.replace("u", "")).
            map(s -> s.length()).reduce(0, Integer::sum);
int res = l.stream().map(s->s.length()).reduce(0, Integer::sum)-tot;

Есть ли лучший способ сделать это?

Ответы [ 4 ]

3 голосов
/ 31 января 2020

Вы можете удалить несколько map с одним map, используя replaceAll

    int tot = l.stream()
               .map(s -> s.replaceAll("[aeiou]", "").length())
               .reduce(0, Integer::sum);

[aeiou], оно будет соответствовать любому символу внутри [] и заменить его пустой строкой

3 голосов
/ 31 января 2020

Как насчет этого:

List<String> vowels = Arrays.asList("a", "e", "i", "o", "u");

int count Arrays.stream(string.split(""))  // generate stream from an String[] of single character strings
    .filter(vowels::contains)  // remove all non-vowels
    .count();  // count the elements remaining
2 голосов
/ 31 января 2020

Я бы разбил его на поток символов, отфильтровал только гласные и затем посчитал:

int tot = l.stream()
  .flatmap(s -> s.chars().stream())
  .filter(c -> c == 'a' || c == 'e' ||c == 'i' ||c == 'o' ||c == 'u')
  .count();
1 голос
/ 31 января 2020

Вы, вероятно, обеспокоены множественными вызовами replace, которые на самом деле не связаны с функциональным программированием. Один из способов заменить эти вызовы - использовать регулярное выражение и replaceAll:

.map(s -> s.replaceAll("[aeiou]", ""))

Эта единственная карта заменяет все 5 карт, которые удаляют гласные.

Регулярным выражением вы также можно удалить все не гласные. Таким образом, вам не нужно вычитать tot:

int vowels = l.stream().map(s -> s.replaceAll("[^aeiou]", ""))
                        .map(s -> s.length()).reduce(0, Integer::sum);
// no need to do anything else!

Теперь у вас еще есть два последовательных map с, вы можете объединить их в один:

int vowels = l.stream().map(s -> s.replaceAll("[^aeiou]", "").length())
                        .reduce(0, Integer::sum);

Это теперь более функционально, потому что я убрал шаг вычитания tot. Эта операция теперь описывается только как композиция функции (что касается уровня абстракции), а не как группа «шагов».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...