Я пытаюсь удалить целочисленные дубликаты списка (String, Int), где мне гарантируется отсутствие дубликатов String.

Можно ли в Haskell оценить что-то подобное:

Я старался:

[(a,b) | (a,b) <- bs, (c,k) <- bs, ((k == b) <= (a == c))]

Но это пока не работает.

Изменить: я хорошо знаю, что вы можете добиться этого, используя более сложный синтаксис. Например, путем рекурсивного поиска в списке дубликатов каждого элемента ...

1
Niclas 21 Ноя 2020 в 13:33

3 ответа

Лучший ответ

(NB: это совершенно новая версия этого ответа. Предыдущая была полностью нестандартной.)

Чтобы лучше понять ваше понимание математического множества, мы можем изменить определение в вашем ответе следующим образом:

uniquesOnly :: (Eq a, Eq b) => [(a, b)] -> [(a, b)]
uniquesOnly bs = 
   [(a,b) | (a,b) <- bs, 
            [(c,d) | (c,d) <- bs, d == b] ==
            [(a,d) | (c,d) <- bs, d == b]]

"для всех (c, d) в bs таких, что d == b следует c == a".

uniquesOnly [(1,1),(2,2),(3,1)] возвращает [(2,2)].

2
Will Ness 24 Ноя 2020 в 06:20

Это возможное решение:

Например, я составил эквивалентное утверждение:

removeDuplicates ::  [(String, Int)] -> [(String, Int)]
removeDuplicates bs = 
   [(a,b) | (a,b) <- bs, 
            length [(c,d) | (c,d) <- bs, d == b] == 1]

Но это не одно и то же утверждение, а только равное.

1
Will Ness 23 Ноя 2020 в 17:02

Существующие ответы не используют гарантию уникальности строк или то, что Int упорядочен. Вот такой.

import Data.List (sortBy, groupBy)
import Data.Function (on)

uniquesOnly :: Ord b => [(a, b)] -> [(a, b)]
uniquesOnly ps
  = [ p
    | [p] <- groupBy ((==) `on` snd) .
             sortBy (compare `on` snd) $ ps ]
1
Will Ness 24 Ноя 2020 в 06:50