How to group similar items in a list using Haskell?Haskell: Combine integers in a list of tuplesCombining the second element of a tuple into a list based on the first elementGroup by first element of a list of tuple and apply function to all grouped second elementsgrouping a list of lists by their first elementHaskell: How do I write a function to combine my list of lists of tuples into a list of tuples?From a list of tuples containing names and id , i want tuples which contains names and list of names which got the similiar idCombine tuples based on first element (Haskell)How to generate the cartesian join of a list of tuples based on their first value?Haskell - Grouping duplicate tuples from a list and making them unique by sndCount elements on ordered listGetting started with HaskellWhat is Haskell used for in the real world?Large-scale design in Haskell?Idiomatic efficient Haskell append?Speed comparison with Project Euler: C vs Python vs Erlang vs HaskellHaskell libraries overview and their qualityHaskell: Lists, Arrays, Vectors, SequencesHow to make fold perform multiple folds based on a categoryOptimizing a Haskell programGroup by first element of a list of tuple and apply function to all grouped second elements

What was an "insurance cover"?

I reverse the source code, you negate the input!

Hilbert's hotel, why can't I repeat it infinitely many times?

Are actors contractually obligated to certain things like going nude/ Sensual Scenes/ Gory Scenes?

Temporarily moving a SQL Server 2016 database to SQL Server 2017 and then moving back. Is it possible?

How could artificial intelligence harm us?

How to influence manager to not schedule team meetings during lunch?

How use custom order in folder on Windows 7 and 10

Why does NASA publish all the results/data it gets?

How is the problem, G has no triangle in Logspace?

What do these pins mean? Where should I plug them in?

Where Does VDD+0.3V Input Limit Come From on IC chips?

Is there any reason nowadays to use a neon indicator lamp instead of an LED?

What are these pixel-level discolored specks? How can I fix it?

How do I extract code from an arduino?

Hiking with a mule or two?

What is the need of methods like GET and POST in the HTTP protocol?

Can multiple wall timers turn lights on or off when required?

Manager encourages me to take day of sick leave instead of PTO, what's in it for him?

I reverse the source code, you negate the output!

What is a Heptagon Number™?

What can a pilot do if an air traffic controller is incapacitated?

Examples of "unsuccessful" theories with afterlives

Pseudo Game of Cups in Python



How to group similar items in a list using Haskell?


Haskell: Combine integers in a list of tuplesCombining the second element of a tuple into a list based on the first elementGroup by first element of a list of tuple and apply function to all grouped second elementsgrouping a list of lists by their first elementHaskell: How do I write a function to combine my list of lists of tuples into a list of tuples?From a list of tuples containing names and id , i want tuples which contains names and list of names which got the similiar idCombine tuples based on first element (Haskell)How to generate the cartesian join of a list of tuples based on their first value?Haskell - Grouping duplicate tuples from a list and making them unique by sndCount elements on ordered listGetting started with HaskellWhat is Haskell used for in the real world?Large-scale design in Haskell?Idiomatic efficient Haskell append?Speed comparison with Project Euler: C vs Python vs Erlang vs HaskellHaskell libraries overview and their qualityHaskell: Lists, Arrays, Vectors, SequencesHow to make fold perform multiple folds based on a categoryOptimizing a Haskell programGroup by first element of a list of tuple and apply function to all grouped second elements






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








22















Given a list of tuples like this:



dic = [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]


How to group items of dic resulting in a list grp where,



grp = [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]


I'm actually a newcomer to Haskell...and seems to be falling in love with it..

Using group or groupBy in Data.List will only group similar adjacent items in a list.
I wrote an inefficient function for this, but it results in memory failures as I need to process a very large coded string list. Hope you would help me find a more efficient way.










share|improve this question





















  • 3





    Looks like a homework or something. Better to add your approach and ask the community for ways to improve it instead of just asking the answer.

    – Satvik
    Sep 13 '12 at 2:07






  • 1





    Sorry, I'm a newcomer to stackoverflow..apologies for not being aware of community rules.

    – td123
    Sep 13 '12 at 2:36

















22















Given a list of tuples like this:



dic = [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]


How to group items of dic resulting in a list grp where,



grp = [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]


I'm actually a newcomer to Haskell...and seems to be falling in love with it..

Using group or groupBy in Data.List will only group similar adjacent items in a list.
I wrote an inefficient function for this, but it results in memory failures as I need to process a very large coded string list. Hope you would help me find a more efficient way.










share|improve this question





















  • 3





    Looks like a homework or something. Better to add your approach and ask the community for ways to improve it instead of just asking the answer.

    – Satvik
    Sep 13 '12 at 2:07






  • 1





    Sorry, I'm a newcomer to stackoverflow..apologies for not being aware of community rules.

    – td123
    Sep 13 '12 at 2:36













22












22








22


4






Given a list of tuples like this:



dic = [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]


How to group items of dic resulting in a list grp where,



grp = [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]


I'm actually a newcomer to Haskell...and seems to be falling in love with it..

Using group or groupBy in Data.List will only group similar adjacent items in a list.
I wrote an inefficient function for this, but it results in memory failures as I need to process a very large coded string list. Hope you would help me find a more efficient way.










share|improve this question
















Given a list of tuples like this:



dic = [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]


How to group items of dic resulting in a list grp where,



grp = [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]


I'm actually a newcomer to Haskell...and seems to be falling in love with it..

Using group or groupBy in Data.List will only group similar adjacent items in a list.
I wrote an inefficient function for this, but it results in memory failures as I need to process a very large coded string list. Hope you would help me find a more efficient way.







haskell






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 13 '12 at 2:39







td123

















asked Sep 13 '12 at 2:04









td123td123

1351 gold badge1 silver badge8 bronze badges




1351 gold badge1 silver badge8 bronze badges










  • 3





    Looks like a homework or something. Better to add your approach and ask the community for ways to improve it instead of just asking the answer.

    – Satvik
    Sep 13 '12 at 2:07






  • 1





    Sorry, I'm a newcomer to stackoverflow..apologies for not being aware of community rules.

    – td123
    Sep 13 '12 at 2:36












  • 3





    Looks like a homework or something. Better to add your approach and ask the community for ways to improve it instead of just asking the answer.

    – Satvik
    Sep 13 '12 at 2:07






  • 1





    Sorry, I'm a newcomer to stackoverflow..apologies for not being aware of community rules.

    – td123
    Sep 13 '12 at 2:36







3




3





Looks like a homework or something. Better to add your approach and ask the community for ways to improve it instead of just asking the answer.

– Satvik
Sep 13 '12 at 2:07





Looks like a homework or something. Better to add your approach and ask the community for ways to improve it instead of just asking the answer.

– Satvik
Sep 13 '12 at 2:07




1




1





Sorry, I'm a newcomer to stackoverflow..apologies for not being aware of community rules.

– td123
Sep 13 '12 at 2:36





Sorry, I'm a newcomer to stackoverflow..apologies for not being aware of community rules.

– td123
Sep 13 '12 at 2:36












5 Answers
5






active

oldest

votes


















15
















Here's my solution:



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

myGroup :: (Eq a, Ord a) => [(a, b)] -> [(a, [b])]
myGroup = map (l -> (fst . head $ l, map snd l)) . groupBy ((==) `on` fst)
. sortBy (comparing fst)


This works by first sorting the list with sortBy:



[(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")] 
=> [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")]


then grouping the list elements by the associated key with groupBy:



[(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")] 
=> [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]]


and then transforming the grouped items to tuples with map:



[[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]] 
=> [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]`)


Testing:



> myGroup dic
[(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]





share|improve this answer



























  • Thank you so much. This really works. I'm actually a newcomer to Haskell and I wasn't aware much about libraries. Thanks again for the clever answer!.

    – td123
    Sep 13 '12 at 2:18











  • @ Mikhail : Hey, are you sure this works even if similar keyed values are not adjacent? for an example if dic = [(1,"aa"),(2,"bb"),(1,"cc")]? result should be [(1, ["aa","cc"]), (2, "bb")].

    – td123
    Sep 13 '12 at 2:22












  • ^@td123 In this case, you should sort the list beforehand.

    – Mikhail Glushenkov
    Sep 13 '12 at 2:24











  • OH..Thank You So much.

    – td123
    Sep 13 '12 at 2:27











  • @td123 I've updated the code to support unsorted lists.

    – Mikhail Glushenkov
    Sep 13 '12 at 2:29



















56
















Whenever possible, reuse library code.



import Data.Map
sortAndGroup assocs = fromListWith (++) [(k, [v]) | (k, v) <- assocs]


Try it out in ghci:



*Main> sortAndGroup [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]
fromList [(1,["bb","cc","aa"]),(2,["aa"]),(3,["gg","ff"])]





share|improve this answer

























  • Really cool solution. Never would've thought of it, but it makes a lot of sense, considering the nature of Data.Map.

    – identity
    Sep 13 '12 at 6:10






  • 1





    This was going to be my answer. I briefly gave pause to think about efficiency though - I use the toList . fromListWith op pattern a lot, but I wonder how expensive the conversions to and from Map are compared to walking over the list and grouping manually.

    – Chris Taylor
    Sep 13 '12 at 8:09






  • 1





    @ChrisTaylor This solution is O(n log n), which is the best you can hope for given the constraints.

    – Daniel Wagner
    Sep 13 '12 at 8:12






  • 1





    @akshay2000 Read the source, of course.

    – Daniel Wagner
    Jul 7 '17 at 16:12






  • 1





    @akshay2000 it's a docs deficiency. it should've mentioned the order, as it already does for insertWith / insertWithKey, which the fromListWith function uses anyhow, judging from its source.

    – Will Ness
    Apr 22 at 7:42


















6
















Also you can use TransformListComp extension, for example:



Prelude> :set -XTransformListComp 
Prelude> import GHC.Exts (groupWith, the)
Prelude GHC.Exts> let dic = [ (1, "aa"), (1, "bb"), (1, "cc") , (2, "aa"), (3, "ff"), (3, "gg")]
Prelude GHC.Exts> [(the key, value) | (key, value) <- dic, then group by key using groupWith]
[(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]





share|improve this answer


































    4

















    1. If the list is not sorted on the first element, I don't think you can do better than O(nlog(n)).



      • One simple way would be to just sort and then use anything from the answer of second part.


      • You can use from Data.Map a map like Map k [a] to use first element of tuple as key and keep on adding to the values.


      • You can write your own complex function, which even after you all the attempts will still take O(nlog(n)).



    2. If list is sorted on the first element as is the case in your example, then the task is trivial for something like groupBy as given in the answer by @Mikhail or use foldr and there are numerous other ways.


    An example of using foldr is here:



     grp :: Eq a => [(a,b)] -> [(a,[b])]
    grp = foldr f []
    where
    f (z,s) [] = [(z,[s])]
    f (z,s) a@((x,y):xs) | x == z = (x,s:y):xs
    | otherwise = (z,[s]):a





    share|improve this answer



























    • Thank you for the info...I'm going to use Data.Map.

      – td123
      Sep 13 '12 at 2:53


















    0
















    -# LANGUAGE TransformListComp #-

    import GHC.Exts
    import Data.List
    import Data.Function (on)

    process :: [(Integer, String)] -> [(Integer, [String])]
    process list = [(the a, b) | let info = [ (x, y) | (x, y) <- list, then sortWith by y ], (a, b) <- info, then group by a using groupWith]





    share|improve this answer



























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );














      draft saved

      draft discarded
















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12398458%2fhow-to-group-similar-items-in-a-list-using-haskell%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      15
















      Here's my solution:



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

      myGroup :: (Eq a, Ord a) => [(a, b)] -> [(a, [b])]
      myGroup = map (l -> (fst . head $ l, map snd l)) . groupBy ((==) `on` fst)
      . sortBy (comparing fst)


      This works by first sorting the list with sortBy:



      [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")] 
      => [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")]


      then grouping the list elements by the associated key with groupBy:



      [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")] 
      => [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]]


      and then transforming the grouped items to tuples with map:



      [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]] 
      => [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]`)


      Testing:



      > myGroup dic
      [(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]





      share|improve this answer



























      • Thank you so much. This really works. I'm actually a newcomer to Haskell and I wasn't aware much about libraries. Thanks again for the clever answer!.

        – td123
        Sep 13 '12 at 2:18











      • @ Mikhail : Hey, are you sure this works even if similar keyed values are not adjacent? for an example if dic = [(1,"aa"),(2,"bb"),(1,"cc")]? result should be [(1, ["aa","cc"]), (2, "bb")].

        – td123
        Sep 13 '12 at 2:22












      • ^@td123 In this case, you should sort the list beforehand.

        – Mikhail Glushenkov
        Sep 13 '12 at 2:24











      • OH..Thank You So much.

        – td123
        Sep 13 '12 at 2:27











      • @td123 I've updated the code to support unsorted lists.

        – Mikhail Glushenkov
        Sep 13 '12 at 2:29
















      15
















      Here's my solution:



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

      myGroup :: (Eq a, Ord a) => [(a, b)] -> [(a, [b])]
      myGroup = map (l -> (fst . head $ l, map snd l)) . groupBy ((==) `on` fst)
      . sortBy (comparing fst)


      This works by first sorting the list with sortBy:



      [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")] 
      => [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")]


      then grouping the list elements by the associated key with groupBy:



      [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")] 
      => [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]]


      and then transforming the grouped items to tuples with map:



      [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]] 
      => [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]`)


      Testing:



      > myGroup dic
      [(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]





      share|improve this answer



























      • Thank you so much. This really works. I'm actually a newcomer to Haskell and I wasn't aware much about libraries. Thanks again for the clever answer!.

        – td123
        Sep 13 '12 at 2:18











      • @ Mikhail : Hey, are you sure this works even if similar keyed values are not adjacent? for an example if dic = [(1,"aa"),(2,"bb"),(1,"cc")]? result should be [(1, ["aa","cc"]), (2, "bb")].

        – td123
        Sep 13 '12 at 2:22












      • ^@td123 In this case, you should sort the list beforehand.

        – Mikhail Glushenkov
        Sep 13 '12 at 2:24











      • OH..Thank You So much.

        – td123
        Sep 13 '12 at 2:27











      • @td123 I've updated the code to support unsorted lists.

        – Mikhail Glushenkov
        Sep 13 '12 at 2:29














      15














      15










      15









      Here's my solution:



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

      myGroup :: (Eq a, Ord a) => [(a, b)] -> [(a, [b])]
      myGroup = map (l -> (fst . head $ l, map snd l)) . groupBy ((==) `on` fst)
      . sortBy (comparing fst)


      This works by first sorting the list with sortBy:



      [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")] 
      => [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")]


      then grouping the list elements by the associated key with groupBy:



      [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")] 
      => [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]]


      and then transforming the grouped items to tuples with map:



      [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]] 
      => [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]`)


      Testing:



      > myGroup dic
      [(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]





      share|improve this answer















      Here's my solution:



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

      myGroup :: (Eq a, Ord a) => [(a, b)] -> [(a, [b])]
      myGroup = map (l -> (fst . head $ l, map snd l)) . groupBy ((==) `on` fst)
      . sortBy (comparing fst)


      This works by first sorting the list with sortBy:



      [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")] 
      => [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")]


      then grouping the list elements by the associated key with groupBy:



      [(1,"aa"),(1,"bb"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg")] 
      => [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]]


      and then transforming the grouped items to tuples with map:



      [[(1,"aa"),(1,"bb"),(1,"cc")],[(2,"aa")],[(3,"ff"),(3,"gg")]] 
      => [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]`)


      Testing:



      > myGroup dic
      [(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Sep 13 '12 at 6:11

























      answered Sep 13 '12 at 2:08









      Mikhail GlushenkovMikhail Glushenkov

      13.9k3 gold badges42 silver badges65 bronze badges




      13.9k3 gold badges42 silver badges65 bronze badges















      • Thank you so much. This really works. I'm actually a newcomer to Haskell and I wasn't aware much about libraries. Thanks again for the clever answer!.

        – td123
        Sep 13 '12 at 2:18











      • @ Mikhail : Hey, are you sure this works even if similar keyed values are not adjacent? for an example if dic = [(1,"aa"),(2,"bb"),(1,"cc")]? result should be [(1, ["aa","cc"]), (2, "bb")].

        – td123
        Sep 13 '12 at 2:22












      • ^@td123 In this case, you should sort the list beforehand.

        – Mikhail Glushenkov
        Sep 13 '12 at 2:24











      • OH..Thank You So much.

        – td123
        Sep 13 '12 at 2:27











      • @td123 I've updated the code to support unsorted lists.

        – Mikhail Glushenkov
        Sep 13 '12 at 2:29


















      • Thank you so much. This really works. I'm actually a newcomer to Haskell and I wasn't aware much about libraries. Thanks again for the clever answer!.

        – td123
        Sep 13 '12 at 2:18











      • @ Mikhail : Hey, are you sure this works even if similar keyed values are not adjacent? for an example if dic = [(1,"aa"),(2,"bb"),(1,"cc")]? result should be [(1, ["aa","cc"]), (2, "bb")].

        – td123
        Sep 13 '12 at 2:22












      • ^@td123 In this case, you should sort the list beforehand.

        – Mikhail Glushenkov
        Sep 13 '12 at 2:24











      • OH..Thank You So much.

        – td123
        Sep 13 '12 at 2:27











      • @td123 I've updated the code to support unsorted lists.

        – Mikhail Glushenkov
        Sep 13 '12 at 2:29

















      Thank you so much. This really works. I'm actually a newcomer to Haskell and I wasn't aware much about libraries. Thanks again for the clever answer!.

      – td123
      Sep 13 '12 at 2:18





      Thank you so much. This really works. I'm actually a newcomer to Haskell and I wasn't aware much about libraries. Thanks again for the clever answer!.

      – td123
      Sep 13 '12 at 2:18













      @ Mikhail : Hey, are you sure this works even if similar keyed values are not adjacent? for an example if dic = [(1,"aa"),(2,"bb"),(1,"cc")]? result should be [(1, ["aa","cc"]), (2, "bb")].

      – td123
      Sep 13 '12 at 2:22






      @ Mikhail : Hey, are you sure this works even if similar keyed values are not adjacent? for an example if dic = [(1,"aa"),(2,"bb"),(1,"cc")]? result should be [(1, ["aa","cc"]), (2, "bb")].

      – td123
      Sep 13 '12 at 2:22














      ^@td123 In this case, you should sort the list beforehand.

      – Mikhail Glushenkov
      Sep 13 '12 at 2:24





      ^@td123 In this case, you should sort the list beforehand.

      – Mikhail Glushenkov
      Sep 13 '12 at 2:24













      OH..Thank You So much.

      – td123
      Sep 13 '12 at 2:27





      OH..Thank You So much.

      – td123
      Sep 13 '12 at 2:27













      @td123 I've updated the code to support unsorted lists.

      – Mikhail Glushenkov
      Sep 13 '12 at 2:29






      @td123 I've updated the code to support unsorted lists.

      – Mikhail Glushenkov
      Sep 13 '12 at 2:29














      56
















      Whenever possible, reuse library code.



      import Data.Map
      sortAndGroup assocs = fromListWith (++) [(k, [v]) | (k, v) <- assocs]


      Try it out in ghci:



      *Main> sortAndGroup [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]
      fromList [(1,["bb","cc","aa"]),(2,["aa"]),(3,["gg","ff"])]





      share|improve this answer

























      • Really cool solution. Never would've thought of it, but it makes a lot of sense, considering the nature of Data.Map.

        – identity
        Sep 13 '12 at 6:10






      • 1





        This was going to be my answer. I briefly gave pause to think about efficiency though - I use the toList . fromListWith op pattern a lot, but I wonder how expensive the conversions to and from Map are compared to walking over the list and grouping manually.

        – Chris Taylor
        Sep 13 '12 at 8:09






      • 1





        @ChrisTaylor This solution is O(n log n), which is the best you can hope for given the constraints.

        – Daniel Wagner
        Sep 13 '12 at 8:12






      • 1





        @akshay2000 Read the source, of course.

        – Daniel Wagner
        Jul 7 '17 at 16:12






      • 1





        @akshay2000 it's a docs deficiency. it should've mentioned the order, as it already does for insertWith / insertWithKey, which the fromListWith function uses anyhow, judging from its source.

        – Will Ness
        Apr 22 at 7:42















      56
















      Whenever possible, reuse library code.



      import Data.Map
      sortAndGroup assocs = fromListWith (++) [(k, [v]) | (k, v) <- assocs]


      Try it out in ghci:



      *Main> sortAndGroup [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]
      fromList [(1,["bb","cc","aa"]),(2,["aa"]),(3,["gg","ff"])]





      share|improve this answer

























      • Really cool solution. Never would've thought of it, but it makes a lot of sense, considering the nature of Data.Map.

        – identity
        Sep 13 '12 at 6:10






      • 1





        This was going to be my answer. I briefly gave pause to think about efficiency though - I use the toList . fromListWith op pattern a lot, but I wonder how expensive the conversions to and from Map are compared to walking over the list and grouping manually.

        – Chris Taylor
        Sep 13 '12 at 8:09






      • 1





        @ChrisTaylor This solution is O(n log n), which is the best you can hope for given the constraints.

        – Daniel Wagner
        Sep 13 '12 at 8:12






      • 1





        @akshay2000 Read the source, of course.

        – Daniel Wagner
        Jul 7 '17 at 16:12






      • 1





        @akshay2000 it's a docs deficiency. it should've mentioned the order, as it already does for insertWith / insertWithKey, which the fromListWith function uses anyhow, judging from its source.

        – Will Ness
        Apr 22 at 7:42













      56














      56










      56









      Whenever possible, reuse library code.



      import Data.Map
      sortAndGroup assocs = fromListWith (++) [(k, [v]) | (k, v) <- assocs]


      Try it out in ghci:



      *Main> sortAndGroup [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]
      fromList [(1,["bb","cc","aa"]),(2,["aa"]),(3,["gg","ff"])]





      share|improve this answer













      Whenever possible, reuse library code.



      import Data.Map
      sortAndGroup assocs = fromListWith (++) [(k, [v]) | (k, v) <- assocs]


      Try it out in ghci:



      *Main> sortAndGroup [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]
      fromList [(1,["bb","cc","aa"]),(2,["aa"]),(3,["gg","ff"])]






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Sep 13 '12 at 3:23









      Daniel WagnerDaniel Wagner

      110k7 gold badges175 silver badges307 bronze badges




      110k7 gold badges175 silver badges307 bronze badges















      • Really cool solution. Never would've thought of it, but it makes a lot of sense, considering the nature of Data.Map.

        – identity
        Sep 13 '12 at 6:10






      • 1





        This was going to be my answer. I briefly gave pause to think about efficiency though - I use the toList . fromListWith op pattern a lot, but I wonder how expensive the conversions to and from Map are compared to walking over the list and grouping manually.

        – Chris Taylor
        Sep 13 '12 at 8:09






      • 1





        @ChrisTaylor This solution is O(n log n), which is the best you can hope for given the constraints.

        – Daniel Wagner
        Sep 13 '12 at 8:12






      • 1





        @akshay2000 Read the source, of course.

        – Daniel Wagner
        Jul 7 '17 at 16:12






      • 1





        @akshay2000 it's a docs deficiency. it should've mentioned the order, as it already does for insertWith / insertWithKey, which the fromListWith function uses anyhow, judging from its source.

        – Will Ness
        Apr 22 at 7:42

















      • Really cool solution. Never would've thought of it, but it makes a lot of sense, considering the nature of Data.Map.

        – identity
        Sep 13 '12 at 6:10






      • 1





        This was going to be my answer. I briefly gave pause to think about efficiency though - I use the toList . fromListWith op pattern a lot, but I wonder how expensive the conversions to and from Map are compared to walking over the list and grouping manually.

        – Chris Taylor
        Sep 13 '12 at 8:09






      • 1





        @ChrisTaylor This solution is O(n log n), which is the best you can hope for given the constraints.

        – Daniel Wagner
        Sep 13 '12 at 8:12






      • 1





        @akshay2000 Read the source, of course.

        – Daniel Wagner
        Jul 7 '17 at 16:12






      • 1





        @akshay2000 it's a docs deficiency. it should've mentioned the order, as it already does for insertWith / insertWithKey, which the fromListWith function uses anyhow, judging from its source.

        – Will Ness
        Apr 22 at 7:42
















      Really cool solution. Never would've thought of it, but it makes a lot of sense, considering the nature of Data.Map.

      – identity
      Sep 13 '12 at 6:10





      Really cool solution. Never would've thought of it, but it makes a lot of sense, considering the nature of Data.Map.

      – identity
      Sep 13 '12 at 6:10




      1




      1





      This was going to be my answer. I briefly gave pause to think about efficiency though - I use the toList . fromListWith op pattern a lot, but I wonder how expensive the conversions to and from Map are compared to walking over the list and grouping manually.

      – Chris Taylor
      Sep 13 '12 at 8:09





      This was going to be my answer. I briefly gave pause to think about efficiency though - I use the toList . fromListWith op pattern a lot, but I wonder how expensive the conversions to and from Map are compared to walking over the list and grouping manually.

      – Chris Taylor
      Sep 13 '12 at 8:09




      1




      1





      @ChrisTaylor This solution is O(n log n), which is the best you can hope for given the constraints.

      – Daniel Wagner
      Sep 13 '12 at 8:12





      @ChrisTaylor This solution is O(n log n), which is the best you can hope for given the constraints.

      – Daniel Wagner
      Sep 13 '12 at 8:12




      1




      1





      @akshay2000 Read the source, of course.

      – Daniel Wagner
      Jul 7 '17 at 16:12





      @akshay2000 Read the source, of course.

      – Daniel Wagner
      Jul 7 '17 at 16:12




      1




      1





      @akshay2000 it's a docs deficiency. it should've mentioned the order, as it already does for insertWith / insertWithKey, which the fromListWith function uses anyhow, judging from its source.

      – Will Ness
      Apr 22 at 7:42





      @akshay2000 it's a docs deficiency. it should've mentioned the order, as it already does for insertWith / insertWithKey, which the fromListWith function uses anyhow, judging from its source.

      – Will Ness
      Apr 22 at 7:42











      6
















      Also you can use TransformListComp extension, for example:



      Prelude> :set -XTransformListComp 
      Prelude> import GHC.Exts (groupWith, the)
      Prelude GHC.Exts> let dic = [ (1, "aa"), (1, "bb"), (1, "cc") , (2, "aa"), (3, "ff"), (3, "gg")]
      Prelude GHC.Exts> [(the key, value) | (key, value) <- dic, then group by key using groupWith]
      [(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]





      share|improve this answer































        6
















        Also you can use TransformListComp extension, for example:



        Prelude> :set -XTransformListComp 
        Prelude> import GHC.Exts (groupWith, the)
        Prelude GHC.Exts> let dic = [ (1, "aa"), (1, "bb"), (1, "cc") , (2, "aa"), (3, "ff"), (3, "gg")]
        Prelude GHC.Exts> [(the key, value) | (key, value) <- dic, then group by key using groupWith]
        [(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]





        share|improve this answer





























          6














          6










          6









          Also you can use TransformListComp extension, for example:



          Prelude> :set -XTransformListComp 
          Prelude> import GHC.Exts (groupWith, the)
          Prelude GHC.Exts> let dic = [ (1, "aa"), (1, "bb"), (1, "cc") , (2, "aa"), (3, "ff"), (3, "gg")]
          Prelude GHC.Exts> [(the key, value) | (key, value) <- dic, then group by key using groupWith]
          [(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]





          share|improve this answer















          Also you can use TransformListComp extension, for example:



          Prelude> :set -XTransformListComp 
          Prelude> import GHC.Exts (groupWith, the)
          Prelude GHC.Exts> let dic = [ (1, "aa"), (1, "bb"), (1, "cc") , (2, "aa"), (3, "ff"), (3, "gg")]
          Prelude GHC.Exts> [(the key, value) | (key, value) <- dic, then group by key using groupWith]
          [(1,["aa","bb","cc"]),(2,["aa"]),(3,["ff","gg"])]






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Sep 13 '12 at 5:30

























          answered Sep 13 '12 at 2:25









          Fedor GogolevFedor Gogolev

          8,7682 gold badges25 silver badges33 bronze badges




          8,7682 gold badges25 silver badges33 bronze badges
























              4

















              1. If the list is not sorted on the first element, I don't think you can do better than O(nlog(n)).



                • One simple way would be to just sort and then use anything from the answer of second part.


                • You can use from Data.Map a map like Map k [a] to use first element of tuple as key and keep on adding to the values.


                • You can write your own complex function, which even after you all the attempts will still take O(nlog(n)).



              2. If list is sorted on the first element as is the case in your example, then the task is trivial for something like groupBy as given in the answer by @Mikhail or use foldr and there are numerous other ways.


              An example of using foldr is here:



               grp :: Eq a => [(a,b)] -> [(a,[b])]
              grp = foldr f []
              where
              f (z,s) [] = [(z,[s])]
              f (z,s) a@((x,y):xs) | x == z = (x,s:y):xs
              | otherwise = (z,[s]):a





              share|improve this answer



























              • Thank you for the info...I'm going to use Data.Map.

                – td123
                Sep 13 '12 at 2:53















              4

















              1. If the list is not sorted on the first element, I don't think you can do better than O(nlog(n)).



                • One simple way would be to just sort and then use anything from the answer of second part.


                • You can use from Data.Map a map like Map k [a] to use first element of tuple as key and keep on adding to the values.


                • You can write your own complex function, which even after you all the attempts will still take O(nlog(n)).



              2. If list is sorted on the first element as is the case in your example, then the task is trivial for something like groupBy as given in the answer by @Mikhail or use foldr and there are numerous other ways.


              An example of using foldr is here:



               grp :: Eq a => [(a,b)] -> [(a,[b])]
              grp = foldr f []
              where
              f (z,s) [] = [(z,[s])]
              f (z,s) a@((x,y):xs) | x == z = (x,s:y):xs
              | otherwise = (z,[s]):a





              share|improve this answer



























              • Thank you for the info...I'm going to use Data.Map.

                – td123
                Sep 13 '12 at 2:53













              4














              4










              4










              1. If the list is not sorted on the first element, I don't think you can do better than O(nlog(n)).



                • One simple way would be to just sort and then use anything from the answer of second part.


                • You can use from Data.Map a map like Map k [a] to use first element of tuple as key and keep on adding to the values.


                • You can write your own complex function, which even after you all the attempts will still take O(nlog(n)).



              2. If list is sorted on the first element as is the case in your example, then the task is trivial for something like groupBy as given in the answer by @Mikhail or use foldr and there are numerous other ways.


              An example of using foldr is here:



               grp :: Eq a => [(a,b)] -> [(a,[b])]
              grp = foldr f []
              where
              f (z,s) [] = [(z,[s])]
              f (z,s) a@((x,y):xs) | x == z = (x,s:y):xs
              | otherwise = (z,[s]):a





              share|improve this answer
















              1. If the list is not sorted on the first element, I don't think you can do better than O(nlog(n)).



                • One simple way would be to just sort and then use anything from the answer of second part.


                • You can use from Data.Map a map like Map k [a] to use first element of tuple as key and keep on adding to the values.


                • You can write your own complex function, which even after you all the attempts will still take O(nlog(n)).



              2. If list is sorted on the first element as is the case in your example, then the task is trivial for something like groupBy as given in the answer by @Mikhail or use foldr and there are numerous other ways.


              An example of using foldr is here:



               grp :: Eq a => [(a,b)] -> [(a,[b])]
              grp = foldr f []
              where
              f (z,s) [] = [(z,[s])]
              f (z,s) a@((x,y):xs) | x == z = (x,s:y):xs
              | otherwise = (z,[s]):a






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Sep 13 '12 at 2:23

























              answered Sep 13 '12 at 2:16









              SatvikSatvik

              10.7k1 gold badge30 silver badges42 bronze badges




              10.7k1 gold badge30 silver badges42 bronze badges















              • Thank you for the info...I'm going to use Data.Map.

                – td123
                Sep 13 '12 at 2:53

















              • Thank you for the info...I'm going to use Data.Map.

                – td123
                Sep 13 '12 at 2:53
















              Thank you for the info...I'm going to use Data.Map.

              – td123
              Sep 13 '12 at 2:53





              Thank you for the info...I'm going to use Data.Map.

              – td123
              Sep 13 '12 at 2:53











              0
















              -# LANGUAGE TransformListComp #-

              import GHC.Exts
              import Data.List
              import Data.Function (on)

              process :: [(Integer, String)] -> [(Integer, [String])]
              process list = [(the a, b) | let info = [ (x, y) | (x, y) <- list, then sortWith by y ], (a, b) <- info, then group by a using groupWith]





              share|improve this answer





























                0
















                -# LANGUAGE TransformListComp #-

                import GHC.Exts
                import Data.List
                import Data.Function (on)

                process :: [(Integer, String)] -> [(Integer, [String])]
                process list = [(the a, b) | let info = [ (x, y) | (x, y) <- list, then sortWith by y ], (a, b) <- info, then group by a using groupWith]





                share|improve this answer



























                  0














                  0










                  0









                  -# LANGUAGE TransformListComp #-

                  import GHC.Exts
                  import Data.List
                  import Data.Function (on)

                  process :: [(Integer, String)] -> [(Integer, [String])]
                  process list = [(the a, b) | let info = [ (x, y) | (x, y) <- list, then sortWith by y ], (a, b) <- info, then group by a using groupWith]





                  share|improve this answer













                  -# LANGUAGE TransformListComp #-

                  import GHC.Exts
                  import Data.List
                  import Data.Function (on)

                  process :: [(Integer, String)] -> [(Integer, [String])]
                  process list = [(the a, b) | let info = [ (x, y) | (x, y) <- list, then sortWith by y ], (a, b) <- info, then group by a using groupWith]






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Apr 12 '16 at 14:27









                  Hari KrishnaHari Krishna

                  1,12911 silver badges28 bronze badges




                  1,12911 silver badges28 bronze badges































                      draft saved

                      draft discarded















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12398458%2fhow-to-group-similar-items-in-a-list-using-haskell%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                      Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                      Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript