Преамбула
Мне пришло в голову, что состояние может рассматриваться как имеющее приоритет, и если задана последовательность пар (agent,status)
, то задача состоит в том, чтобы выбрать только самый высокийстатус приоритета для каждого агента.К сожалению, статус не является строго типизированным с явным порядком, определенным таким образом, но ... поскольку это строка с двумя значениями, мы можем смело использовать порядок строк как имеющий соответствие 1: 1 приоритету.
В обоих моих ответах используются два полезных факта:
При естественном упорядочении строк "FAIL" < "PASS"
, поэтому:
List("PASS", "FAIL", "PASS").sorted.head = "FAIL"
Для двоихкортежи (x,a)
и (x,b)
, (x,a) > (x, b)
, если (a > b)
ОБНОВЛЕННЫЙ ОТВЕТ
val solution = l.sorted.reverse.toMap
При преобразовании Seq[(A,B)]
до Map[A,B]
с помощью метода .toMap
, каждый «ключ» в исходной последовательности кортежей может появиться в результирующей карте только один раз.Как это происходит, преобразование использует последний такой случай.
l.sorted.reverse = List(
(Agent 2,PASS), // <-- Last "Agent 2"
(Agent 1,FAIL), // <-- Last "Agent 1"
(Agent,PASS),
(Agent,PASS),
(Agent,FAIL)) // <-- Last "Agent"
l.sorted.reverse.toMap = Map(
Agent 2 -> PASS,
Agent 1 -> FAIL,
Agent -> FAIL)
ОРИГИНАЛЬНЫЙ ОТВЕТ
Начиная с ответа ...
val oldSolution = (l groupBy (_._1)) mapValues {_.sorted.head._2}
... а затем показывает мою работу:)
//group
l groupBy (_._1) = Map(
Agent 2 -> List((Agent 2,PASS)),
Agent 1 -> List((Agent 1,FAIL)),
Agent -> List((Agent,PASS), (Agent,FAIL), (Agent,PASS))
)
//extract values
(l groupBy (_._1)) mapValues {_.map(_._2)} = Map(
Agent 2 -> List(PASS),
Agent 1 -> List(FAIL),
Agent -> List(PASS, FAIL, PASS))
//sort
(l groupBy (_._1)) mapValues {_.map(_._2).sorted} = Map(
Agent 2 -> List(PASS),
Agent 1 -> List(FAIL),
Agent -> List(FAIL, PASS, PASS))
//head
(l groupBy (_._1)) mapValues {_.map(_._2).sorted.head} = Map(
Agent 2 -> PASS,
Agent 1 -> FAIL,
Agent -> FAIL)
Однако вы можете напрямую отсортировать пары agent -> status
без необходимости сначала извлекать _2
:
//group & sort
(l groupBy (_._1)) mapValues {_.sorted} = Map(
Agent 2 -> List((Agent 2,PASS)),
Agent 1 -> List((Agent 1,FAIL)),
Agent -> List((Agent,FAIL), (Agent,PASS), (Agent,PASS)))
//extract values
(l groupBy (_._1)) mapValues {_.sorted.head._2} = Map(
Agent 2 -> PASS,
Agent 1 -> FAIL,
Agent -> FAIL)
В любом случае, не стесняйтесь конвертировать обратно в список пар, если хотите:
l.sorted.reverse.toMap.toList = List(
(Agent 2, PASS),
(Agent 1, FAIL),
(Agent, FAIL))