Применение частичных функций там, где они определены, и другой функции, где нет

Это мотивационный пример, учитывая:

List((1,2), (2,1), (3,1))

Я хотел бы вернуться:

List((1,2),(3,1))

Я пытался сделать это несколькими способами. Первый:

List((1,2), (2,1), (3,1)) map { case (a,b) => if (a > b) (a,b) else (b,a) } 
distinct

Затем я попытался использовать кортеж:

List((1,2), (3,4), (2,1)) map { t => if (t._1 <= t._2) t else t.swap }

затем определение частичной функции немного по-другому:

val pf: PartialFunction[(Int,Int), (Int,Int)] = {
  case (i, j) if i >= j => (j, i)
}

List((1,2), (3,4), (2,1)) map pf distinct

Есть ли способ применить PartialFunction только к элементам, для которых определено? или каким-то образом соединить PF с Identity.


person Joselo    schedule 09.12.2014    source источник
comment
возможный дубликат кортежей фильтра Scala (x, y) == (y, x)   -  person The Archetypal Paul    schedule 09.12.2014
comment
чтобы ответить на ваш другой вопрос: есть ли способ применить PartialFunction только к элементам, для которых определено? - collect делает именно это. Но я думаю, вы имеете в виду и оставляете элементы, для которых он не определен, без изменений?   -  person The Archetypal Paul    schedule 09.12.2014
comment
Как правило, частичная функция не возвращает тот же тип, что и ее параметр. Таким образом, на самом деле нет места для универсального метода apply-this-partial-func-if-defined-else-identity. Учитывая это, я думаю, что ваша предыдущая версия с регистром по умолчанию достаточно ясна.   -  person The Archetypal Paul    schedule 09.12.2014
comment
Отменил закрытое голосование, поскольку вы изменили суть вопроса.   -  person The Archetypal Paul    schedule 09.12.2014
comment
да, это то, что делает collect, но это ответ на ваш вопрос, как указано. Однако вы этого не хотите - вы также хотите, если не определено использование идентификатора   -  person The Archetypal Paul    schedule 09.12.2014
comment
Не стесняйтесь удалять эти комментарии, имеет большой смысл то, что вы говорите в своем третьем комментарии.   -  person Joselo    schedule 09.12.2014
comment
Подождите минутку, у меня есть полезный ответ для вас :)   -  person The Archetypal Paul    schedule 09.12.2014
comment
@JamesIry опередил меня.   -  person The Archetypal Paul    schedule 09.12.2014


Ответы (1)


Вот еще одна форма для полноты картины

List((1,2), (2,1), (3,1)) map { case x@(i,j) => if (i >= j) (j,i) else x } distinct

Что в основном то же самое, что и несколько других ваших форм.

Есть ли способ применить PartialFunction только к элементам, для которых определено? или каким-то образом соединить PF с Identity.

Да. применить или еще.

В этом случае очень мало причин проверять, где ваша частичная функция определена, а где нет, потому что объем работы, необходимый для проверки определенности, будет таким же, как работа, которую должна выполнить общая функция, прежде чем выяснить, что делать ( то есть сравнение двух элементов).

Но если вы действительно хотите

List((1,2), (3,4), (2,1)) map {x => pf.applyOrElse(x, identity[(Int, Int)])} distinct
person James Iry    schedule 09.12.2014
comment
Ваша PartialFunction — это тотальная функция. Не после последнего редактирования, это не :( - person The Archetypal Paul; 09.12.2014
comment
Да! :( Я пытаюсь отразить то, что я хочу спросить :) и спасибо, что я сделал это! :П - person Joselo; 09.12.2014
comment
Да, проклятые правки испортили мои совершенно хорошие ответы. Я обновил свой ответ, чтобы отразить новый код. - person James Iry; 09.12.2014
comment
Да :( извините за это - person Joselo; 09.12.2014
comment
Ах, слишком медленно. Я только что придумал то же самое applyOrElse! - person The Archetypal Paul; 09.12.2014