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;
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
add a comment
|
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
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
add a comment
|
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
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
haskell
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
add a comment
|
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
add a comment
|
5 Answers
5
active
oldest
votes
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"])]
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
add a comment
|
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"])]
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 thetoList . fromListWith op
pattern a lot, but I wonder how expensive the conversions to and fromMap
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 forinsertWith
/insertWithKey
, which thefromListWith
function uses anyhow, judging from its source.
– Will Ness
Apr 22 at 7:42
|
show 8 more comments
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"])]
add a comment
|
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 likeMap 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)).
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
Thank you for the info...I'm going to use Data.Map.
– td123
Sep 13 '12 at 2:53
add a comment
|
-# 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]
add a comment
|
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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"])]
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
add a comment
|
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"])]
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
add a comment
|
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"])]
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"])]
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
add a comment
|
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
add a comment
|
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"])]
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 thetoList . fromListWith op
pattern a lot, but I wonder how expensive the conversions to and fromMap
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 forinsertWith
/insertWithKey
, which thefromListWith
function uses anyhow, judging from its source.
– Will Ness
Apr 22 at 7:42
|
show 8 more comments
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"])]
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 thetoList . fromListWith op
pattern a lot, but I wonder how expensive the conversions to and fromMap
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 forinsertWith
/insertWithKey
, which thefromListWith
function uses anyhow, judging from its source.
– Will Ness
Apr 22 at 7:42
|
show 8 more comments
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"])]
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"])]
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 thetoList . fromListWith op
pattern a lot, but I wonder how expensive the conversions to and fromMap
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 forinsertWith
/insertWithKey
, which thefromListWith
function uses anyhow, judging from its source.
– Will Ness
Apr 22 at 7:42
|
show 8 more comments
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 thetoList . fromListWith op
pattern a lot, but I wonder how expensive the conversions to and fromMap
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 forinsertWith
/insertWithKey
, which thefromListWith
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
|
show 8 more comments
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"])]
add a comment
|
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"])]
add a comment
|
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"])]
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"])]
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
add a comment
|
add a comment
|
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 likeMap 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)).
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
Thank you for the info...I'm going to use Data.Map.
– td123
Sep 13 '12 at 2:53
add a comment
|
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 likeMap 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)).
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
Thank you for the info...I'm going to use Data.Map.
– td123
Sep 13 '12 at 2:53
add a comment
|
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 likeMap 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)).
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
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 likeMap 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)).
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
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
add a comment
|
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
add a comment
|
-# 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]
add a comment
|
-# 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]
add a comment
|
-# 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]
-# 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]
answered Apr 12 '16 at 14:27
Hari KrishnaHari Krishna
1,12911 silver badges28 bronze badges
1,12911 silver badges28 bronze badges
add a comment
|
add a comment
|
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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