F #: группировка сложного списка - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь сгруппировать список по каждому элементу списка игроков

let playersScore= [ 
  (["Player 1";"Player 2";], "First Game");
  (["Player 2";"Player 3";"Player 4";], "Second Game");
  (["Player 3"], "Third Game");
  (["Player 1";"Player 2";"Player 3";"Player 4";], "Last Game")] : scorePlayerItem list

Что я хочу получить, так это найти, какой игрок присоединился к каким играм, как

(string * string list) list

Например, согласно этому списку

  1. Player1 -> Первая игра, Последняя игра
  2. Player2 -> Первая игра, Вторая игра
  3. Player3 -> Вторая, третья игра, Последняя игра
  4. Player4 -> Вторая игра, Последняя игра

Я пытался использовать List.groupBy, но не смог этого добиться.Мне просто не удалось сгруппировать предметы по каждому элементу списка игроков.

Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 25 сентября 2018

Вот довольно простое решение:

let groups =
    playersScore
    |> List.collect (fun (players, game) -> players |> List.map (fun player -> player, game))
    |> List.groupBy (fun (player, _) -> player)
    |> Map.ofList
    |> Map.map (fun _ games -> games |> List.map snd)

Разбейте список списков на плоскую структуру, сгруппируйте их по игроку, затем преобразуйте в карту с игроком в качестве ключа и, наконец, отобразите картузначения, чтобы получить только название игры.Это дает следующую карту:

map
  [("Player 1", ["First Game"; "Last Game"]);
   ("Player 2", ["First Game"; "Second Game"; "Last Game"]);
   ("Player 3", ["Second Game"; "Third Game"; "Last Game"]);
   ("Player 4", ["Second Game"; "Last Game"])]

РЕДАКТИРОВАТЬ

Чтобы сохранить вещи в виде списка, вы можете просто использовать List.map вместо Map.ofList и Map.map:

let groups =
    playersScore
    |> List.collect (fun (players, game) -> players |> List.map (fun player -> player, game))
    |> List.groupBy (fun (player, _) -> player)
    |> List.map (fun (player, games) -> player, games |> List.map snd)

Возвращает эквивалентный результат в виде списка:

[("Player 1", ["First Game"; "Last Game"]);
 ("Player 2", ["First Game"; "Second Game"; "Last Game"]);
 ("Player 3", ["Second Game"; "Third Game"; "Last Game"]);
 ("Player 4", ["Second Game"; "Last Game"])]
...