Ayrat
ща попробую на for написать
Vasily
Будет покрасивше
Vasily
Vladislav
Vladislav
Ayrat
@vshapenko императивненько
def stockSummary2(lstOfArt: Array[String], lstOfCat: Array[String]): String = {
val catWithQtyMap: Map[String, Int] = Map().withDefaultValue(0)
lstOfArt foreach(art => {
val artMatch = artRegex.findFirstMatchIn(art)
if (artMatch.isEmpty)
throw new Exception(s"wrong art - $art")
val category = artMatch.get.group(1)
val qty = artMatch.get.group(2).toInt
val oldQty = catWithQtyMap(category)
catWithQtyMap += (category -> (oldQty + qty))
})
lstOfCat.toStream
.map(cat => s"($cat : ${catWithQtyMap(cat)})")
.mkString(" - ")
}
Vasily
А при чем тут foreach?
Ayrat
ну в той ссылке что ты послал это был один из двух вариантов!
Vasily
Но пользуются for!!!!!11111
Ayrat
бля
Ayrat
я не знаю как сделать for и group by
Ayrat
я тупой наверное
Ayrat
ну точнее я вот сделал - мутабельная мапа и for
Vasily
for{ art<-listofArt if artRegex.findFirstMatchIn(art).isEmpty...
Vasily
groupby потом
Doge
Так. нужен код ревью от любителей скалировать.
примитивная задача с кодварс
есть массив строк вида
"ABCD 20", где первая буква - категория, дальше неизвестное кол-во рандомных букв и цифра - кол-во товара в категории.
Дан массив таких товаров и дан массив категорий.
Надо найти кол-во товаров по данным категориям.
Пример
товары = Array("ABART 20", "CDXEF 50", "BKWRK 25", "BTSQZ 89", "DRTYM 60")
категории = Array("A", "B", "C", "W")
результат
(A : 20) - (B : 114) - (C : 50) - (W : 0)
мой говнокод
val artRegex: Regex = raw"([A-Z])[A-Z]+ (\d+)".r
def stockSummary(lstOfArt: Array[String], lstOfCat: Array[String]): String = {
val catMap =
lstOfArt.toStream.map(art =>
artRegex.findFirstMatchIn(art) match {
case Some(matches) => (matches.group(1), matches.group(2).toInt)
case None => throw new Exception(s"wrong art - $art")
})
.groupBy(x => x._1)
.map(x => {
val sum = x._2.map(x => x._2).sum
val cat = x._1
(cat, sum)
})
.withDefaultValue(0)
lstOfCat.toStream
.map(cat => {
val sum = catMap(cat)
s"($cat : $sum)"
})
.mkString(" - ")
}
он рабочий, но мне нужно знать как его улучшить, где тут подвохи, может я тут неоптимально чот делаю. И ещё фишки как упростить, укоротить и всё такое прочее. Не факт что я их заюзаю мне их просто надо знать, потому что я не шарю
суммоню всех известных скалистов
@vshapenko @DogeShibu @grishace @fvnever
Особо не вчитывался, пишу то, за что взгляд сходу зацепился.
1. Инстанс регекспа - это сразу unapplier, его можно использовать в паттерн матчах.
2. Вместо исключения лучше Either, если уж про ФП говорим
3. Сложные функции из map лучше перенести в отдельную локальную функцию.
Ayrat
Ayrat
ммм
Крылатый
Пацаны, го лепить идеальные блины. https://nplus1.ru/news/2019/06/17/perfect-blinchik
Ayrat
эта штука выдаёт не стрим, а тупль
Ayrat
я чот в местной системе типов не догоняю походу
Анна
@omgszer пиши на котлине 🤓
Ayrat
@omgszer пиши на котлине 🤓
Чот пока я скалой не впечатлился. Много неявных преобразований из нормальных типов в не пойми что. Подозреваю что в котлине та же трабла
Doge
Это если относительно эквивалентными преобразованиями переписывать не особо вчитываясь.
Ayrat
Во, выглядит збс. Очень большое спасибо
Doge
Во, выглядит збс. Очень большое спасибо
Проверь на всякий случай, что работает. Я не проверял.
Обрати ещё внимание на фукнцию collect и на тип PartialFunction, очень интересная штука, которая во многих случаях может пригодиться.
Vasily
Во, уже больше похоже на нечитаемый скала код
Vladislav
Ayrat
Ayrat
то есть не инпуты обрабатываются этим матчем
Doge
Никак не могу найти нормального туториала, который можно скинуть на эту тему.
Vasily
orElse цепляешь, как я понял
Ayrat
Ayrat
я хочу объявить кейз класс и деконстракт патерн сразу
Ayrat
но тогда сам патерн и конструктор конфликтуют
Doge
Ayrat
одноимённые
Ayrat
то есть к типу прицепить unapply в общем-то хочу
Ayrat
или их к типам нельзя прицеплять именно потому что неясно где конструктор, а где деконстракт?
Ayrat
Ахха. в кейз классе уже unapply генерится. Наверное это дичь
Doge
Viacheslav
Что-то первоапрельская шутка перестала быть шуткой
Vasily
Бля, Visual studio на маке - какой-то пздц
x
Vasily
На макоси, хорошо
Vasily
Там какой-то треш с чтением из консоли
Vasily
И выводом на консоль
Viacheslav
Vladislav
Мои знакомые маководы так делали
Vasily
Какой треш?
Берешь пишешь программку, которая говорит "Введите число"
Vasily
И Console.ReadLine потом
Ayrat
@DogeShibu ешё вопрос.
вот в такой конструкции, если lstOfCat массив - map сделает ещё один массив?
lstOfCat
.map(cat => s"($cat : ${catMap(cat)})")
.mkString(" - ")
Ayrat
я подозреваю что да
Vasily
Надо байткод смотреть :)
Vasily
В скале же все call by name
Ayrat
ну по скалокоду должен сделать.
там map у траверсаблЛайк вызывается
Doge
Ayrat
Vasily
ByteString
Ayrat
lstOfCat.toStream
.map(cat => s"($cat : ${catMap(cat)})")
.mkString(" - ")
Vasily
Вроде как
Vasily
Из того, что я в скала коде видел
Ayrat
и хопля, и перформас збс сразу стало
Doge
Как и сами Stream'ы
Ayrat
Ayrat
Ща попробую на жаба стримах сделать (я вообще думал это они и есть лол)
Ayrat
@DogeShibu давай последний вопрос. У меня эта срань отказывается компилиться:
import java.util
import java.util.stream.Collectors
import scala.util.Try
import scala.util.matching.Regex
object IsInt {
def unapply(arg: String): Option[Int] =
Try(arg.toInt).toOption
}
final case class Art(name: String, qty: Int)
object StockList {
val ArtRegex: Regex = raw"([A-Z])[A-Z]+ (\d+)".r
def stockSummary(lstOfArt: Array[String], lstOfCat: Array[String]): String = {
val catMap: util.Map[String, util.List[Art]] =
util.Arrays.stream(lstOfArt)
.map((article: String) =>
article match {
case ArtRegex(cat, IsInt(qty)) => Art(cat, qty)
case _ => throw new Exception(s"wrong article $article")
}
)
.collect(Collectors.groupingBy((x: Art) => x.name))
util.Arrays.stream(lstOfCat)
.map(cat => {
val allQtys = catMap.getOrDefault(cat, util.List.of())
val qtySum = allQtys.stream().map(_.qty).mapToInt(_).sum()
s"($cat : $qtySum)"
})
.collect(Collectors.joining(" - "))
}
}
ошибки вида
Error:(20, 10) no type parameters for method map: (x$1: java.util.function.Function[_ >: String, _ <: R])java.util.stream.Stream[R] exist so that it can be applied to arguments (java.util.function.Function[String,Art])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : java.util.function.Function[String,Art]
required: java.util.function.Function[_ >: String, _ <: ?R]
Note: String <: Any, but Java-defined trait Function is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
.map((article: String) =>
если я убираю все тайп аннотейшны из лямбд или из val catMap: util.Map[String, util.List[Art]] =, он вообще везде ставит Nothing и всё валится. Я чот не понимаю наверное глобальное, да?
Ayrat
я попробовал жаба стримы, выглядят кошмарно конечно. надо постоянно приводить в стрим на любой чих. Для работы с разными стримами надо их надо конвертитьв IntStream, группировка через Collectors..