Так как мне нравятся каракули и стрелки, чтобы прояснить понятия ... давайте начнем!
Предположим, что у вас есть 4 строки: ваша цель - объединить такие строки в одну. В основном вы начинаете с типа и заканчиваете с тем же типом.
Вы можете добиться этого с помощью
String res = Arrays.asList("one", "two","three","four")
.stream()
.reduce("",
(accumulatedStr, str) -> accumulatedStr + str); //accumulator
, и это поможет вам визуализировать происходящее:
Функция аккумулятора преобразует, шаг за шагом, элементы в вашем (красном) потоке до конечного уменьшенного (зеленого) значения. Функция аккумулятора просто преобразует объект String
в другой String
.
Предположим, что у вас есть те же 4 строки: ваша новая цель - суммируйте их длины, и вы хотите распараллелить свой поток.
Что вам нужно, это примерно так:
int length = Arrays.asList("one", "two","three","four")
.parallelStream()
.reduce(0,
(accumulatedInt, str) -> accumulatedInt + str.length(), //accumulator
(accumulatedInt, accumulatedInt2) -> accumulatedInt + accumulatedInt2); //combiner
, и это схема происходящего
Здесь функция аккумулятора (a BiFunction
) позволяет преобразовать ваши данные String
в данные int
. Будучи параллельным потоком, он разделяется на две (красные) части, каждая из которых разрабатывается независимо друг от друга и производит столько же частичных (оранжевых) результатов. Определение объединителя необходимо для предоставления правила объединения частичных результатов int
в конечный (зеленый) int
.
Что если вы не хотите распараллелить свой поток? Ну, комбайнер должен быть предоставлен в любом случае, но он никогда не будет вызван, если не будет получено никаких частичных результатов.
Нет необходимости в подстроке , просто используйте gsub :
gsub( " .*$", "", dob )
# [1] "9/9/43" "9/17/88" "11/21/48"
Пространство (), то любой символ (
.
) любое количество раз (*
) до конца строки ($
). См. ? Regex , чтобы узнать регулярные выражения.
Библиотека stringr
содержит функцию, адаптированную к этой задаче.
library(stringr)
word(dob,1)
# [1] "9/9/43" "9/17/88" "11/21/48"
word(dob,-1)
– dpel
15 May 2018 в 15:27
Я часто использую strsplit
для подобных проблем, но мне понравилось, как был простой ответ Ромена. Я подумал, что было бы интересно сравнить решение Ромена с ответом strsplit
:
Вот решение strsplit
:
sapply(strsplit(dob, "\\s+"), "[", 1)
Использование пакета microbenchmark и dob <- rep(dob, 1000)
с исходные данные:
Unit: milliseconds
expr min lq median
gsub(" .*$", "", dob) 4.228843 4.247969 4.258232
sapply(strsplit(dob, "\\\\s+"), "[", 1) 14.438241 14.558832 14.634638
uq max neval
4.268029 5.081608 1000
14.756628 53.344984 1000
Явным победителем на машине Win 7 является регулярное выражение gsub
от Romain. Спасибо за ответ и объяснение Ромен.
sub
, так как есть только одна конечная позиция строки. – Wiktor Stribiżew 12 October 2016 в 21:50