Get the first elements of a list of tuples
I have this list of tuples
[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"
I came up with this code, but it only gives me the replicate of the first tuple.
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"
I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.
list haskell tuples replicate
add a comment |
I have this list of tuples
[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"
I came up with this code, but it only gives me the replicate of the first tuple.
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"
I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.
list haskell tuples replicate
1
It's usually much clearer not to work withfst
andsnd
(and definitely not withhead
or!!
) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.
– leftaroundabout
Nov 16 '18 at 0:38
2
f = (>>= uncurry replicate)
is the fancy-pants approach.
– amalloy
Nov 16 '18 at 1:05
1
Your list isils
in[s | (n,c) <- ils, s <- replicate n c]
produces the output you require.
– fp_mora
Nov 16 '18 at 2:20
map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.
– Manoj R
Nov 16 '18 at 5:44
add a comment |
I have this list of tuples
[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"
I came up with this code, but it only gives me the replicate of the first tuple.
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"
I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.
list haskell tuples replicate
I have this list of tuples
[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"
I came up with this code, but it only gives me the replicate of the first tuple.
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"
I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.
list haskell tuples replicate
list haskell tuples replicate
asked Nov 16 '18 at 0:29
Tyler JoeTyler Joe
646
646
1
It's usually much clearer not to work withfst
andsnd
(and definitely not withhead
or!!
) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.
– leftaroundabout
Nov 16 '18 at 0:38
2
f = (>>= uncurry replicate)
is the fancy-pants approach.
– amalloy
Nov 16 '18 at 1:05
1
Your list isils
in[s | (n,c) <- ils, s <- replicate n c]
produces the output you require.
– fp_mora
Nov 16 '18 at 2:20
map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.
– Manoj R
Nov 16 '18 at 5:44
add a comment |
1
It's usually much clearer not to work withfst
andsnd
(and definitely not withhead
or!!
) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.
– leftaroundabout
Nov 16 '18 at 0:38
2
f = (>>= uncurry replicate)
is the fancy-pants approach.
– amalloy
Nov 16 '18 at 1:05
1
Your list isils
in[s | (n,c) <- ils, s <- replicate n c]
produces the output you require.
– fp_mora
Nov 16 '18 at 2:20
map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.
– Manoj R
Nov 16 '18 at 5:44
1
1
It's usually much clearer not to work with
fst
and snd
(and definitely not with head
or !!
) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.– leftaroundabout
Nov 16 '18 at 0:38
It's usually much clearer not to work with
fst
and snd
(and definitely not with head
or !!
) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.– leftaroundabout
Nov 16 '18 at 0:38
2
2
f = (>>= uncurry replicate)
is the fancy-pants approach.– amalloy
Nov 16 '18 at 1:05
f = (>>= uncurry replicate)
is the fancy-pants approach.– amalloy
Nov 16 '18 at 1:05
1
1
Your list is
ils
in [s | (n,c) <- ils, s <- replicate n c]
produces the output you require.– fp_mora
Nov 16 '18 at 2:20
Your list is
ils
in [s | (n,c) <- ils, s <- replicate n c]
produces the output you require.– fp_mora
Nov 16 '18 at 2:20
map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.
– Manoj R
Nov 16 '18 at 5:44
map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.
– Manoj R
Nov 16 '18 at 5:44
add a comment |
3 Answers
3
active
oldest
votes
Since you already know how to find the correct answer for a single element, all you need is a little recursion
func :: [(Int, a)] -> [a]
func =
func ((n, elem):rest) = (replicate n elem) ++ (func rest)
Mapping the values should also work. You just need to concatenate the resulting strings into one.
func :: [(Int, a)] -> [a]
func xs = concat $ map func2 xs where
func2 (n, elem) = replicate n elem
Or, if you are familiar with currying:
func :: [(Int, a)] -> [a]
func xs = concat $ map (uncurry replicate) xs
Finally, if you are comfortable using function composition, the definition becomes:
func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)
Using concat
and map
is so common, there is a function to do just that. It's concatMap
.
func :: [(Int, a)] -> [a]
func = concatMap (uncurry replicate)
add a comment |
You are correct about trying to use map
. But first lets see why your code did not work
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.
Before using map
lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.
generate =
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs
Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.
generate =
generate ((x,y):xs) = replicate x y ++ generate xs
Now coming to map, so map will apply your function to every element of the list, here's the first try
generate (x,y) = replicate x y
map generate xs
The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.
Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).
--first parameter is the function to apply, second is the accumulator, third is your list
foldr step xs
where step (x,y) acc =
(replicate x y) ++ acc
Again here I have used pattern matching in the function step to extract the elements of the tuple out.
add a comment |
Let
ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
in
concat [replicate i x | (i, x) <- ls]
will give
"aaaabccaadeeee"
The point-free version
concat . map (uncurry replicate)
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/3.0/"u003ecc by-sa 3.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%2f53329755%2fget-the-first-elements-of-a-list-of-tuples%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Since you already know how to find the correct answer for a single element, all you need is a little recursion
func :: [(Int, a)] -> [a]
func =
func ((n, elem):rest) = (replicate n elem) ++ (func rest)
Mapping the values should also work. You just need to concatenate the resulting strings into one.
func :: [(Int, a)] -> [a]
func xs = concat $ map func2 xs where
func2 (n, elem) = replicate n elem
Or, if you are familiar with currying:
func :: [(Int, a)] -> [a]
func xs = concat $ map (uncurry replicate) xs
Finally, if you are comfortable using function composition, the definition becomes:
func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)
Using concat
and map
is so common, there is a function to do just that. It's concatMap
.
func :: [(Int, a)] -> [a]
func = concatMap (uncurry replicate)
add a comment |
Since you already know how to find the correct answer for a single element, all you need is a little recursion
func :: [(Int, a)] -> [a]
func =
func ((n, elem):rest) = (replicate n elem) ++ (func rest)
Mapping the values should also work. You just need to concatenate the resulting strings into one.
func :: [(Int, a)] -> [a]
func xs = concat $ map func2 xs where
func2 (n, elem) = replicate n elem
Or, if you are familiar with currying:
func :: [(Int, a)] -> [a]
func xs = concat $ map (uncurry replicate) xs
Finally, if you are comfortable using function composition, the definition becomes:
func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)
Using concat
and map
is so common, there is a function to do just that. It's concatMap
.
func :: [(Int, a)] -> [a]
func = concatMap (uncurry replicate)
add a comment |
Since you already know how to find the correct answer for a single element, all you need is a little recursion
func :: [(Int, a)] -> [a]
func =
func ((n, elem):rest) = (replicate n elem) ++ (func rest)
Mapping the values should also work. You just need to concatenate the resulting strings into one.
func :: [(Int, a)] -> [a]
func xs = concat $ map func2 xs where
func2 (n, elem) = replicate n elem
Or, if you are familiar with currying:
func :: [(Int, a)] -> [a]
func xs = concat $ map (uncurry replicate) xs
Finally, if you are comfortable using function composition, the definition becomes:
func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)
Using concat
and map
is so common, there is a function to do just that. It's concatMap
.
func :: [(Int, a)] -> [a]
func = concatMap (uncurry replicate)
Since you already know how to find the correct answer for a single element, all you need is a little recursion
func :: [(Int, a)] -> [a]
func =
func ((n, elem):rest) = (replicate n elem) ++ (func rest)
Mapping the values should also work. You just need to concatenate the resulting strings into one.
func :: [(Int, a)] -> [a]
func xs = concat $ map func2 xs where
func2 (n, elem) = replicate n elem
Or, if you are familiar with currying:
func :: [(Int, a)] -> [a]
func xs = concat $ map (uncurry replicate) xs
Finally, if you are comfortable using function composition, the definition becomes:
func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)
Using concat
and map
is so common, there is a function to do just that. It's concatMap
.
func :: [(Int, a)] -> [a]
func = concatMap (uncurry replicate)
answered Nov 16 '18 at 1:15
merlynmerlyn
1,77011323
1,77011323
add a comment |
add a comment |
You are correct about trying to use map
. But first lets see why your code did not work
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.
Before using map
lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.
generate =
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs
Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.
generate =
generate ((x,y):xs) = replicate x y ++ generate xs
Now coming to map, so map will apply your function to every element of the list, here's the first try
generate (x,y) = replicate x y
map generate xs
The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.
Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).
--first parameter is the function to apply, second is the accumulator, third is your list
foldr step xs
where step (x,y) acc =
(replicate x y) ++ acc
Again here I have used pattern matching in the function step to extract the elements of the tuple out.
add a comment |
You are correct about trying to use map
. But first lets see why your code did not work
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.
Before using map
lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.
generate =
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs
Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.
generate =
generate ((x,y):xs) = replicate x y ++ generate xs
Now coming to map, so map will apply your function to every element of the list, here's the first try
generate (x,y) = replicate x y
map generate xs
The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.
Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).
--first parameter is the function to apply, second is the accumulator, third is your list
foldr step xs
where step (x,y) acc =
(replicate x y) ++ acc
Again here I have used pattern matching in the function step to extract the elements of the tuple out.
add a comment |
You are correct about trying to use map
. But first lets see why your code did not work
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.
Before using map
lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.
generate =
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs
Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.
generate =
generate ((x,y):xs) = replicate x y ++ generate xs
Now coming to map, so map will apply your function to every element of the list, here's the first try
generate (x,y) = replicate x y
map generate xs
The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.
Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).
--first parameter is the function to apply, second is the accumulator, third is your list
foldr step xs
where step (x,y) acc =
(replicate x y) ++ acc
Again here I have used pattern matching in the function step to extract the elements of the tuple out.
You are correct about trying to use map
. But first lets see why your code did not work
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.
Before using map
lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.
generate =
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs
Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.
generate =
generate ((x,y):xs) = replicate x y ++ generate xs
Now coming to map, so map will apply your function to every element of the list, here's the first try
generate (x,y) = replicate x y
map generate xs
The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.
Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).
--first parameter is the function to apply, second is the accumulator, third is your list
foldr step xs
where step (x,y) acc =
(replicate x y) ++ acc
Again here I have used pattern matching in the function step to extract the elements of the tuple out.
answered Nov 16 '18 at 1:16
peeyush singhpeeyush singh
536316
536316
add a comment |
add a comment |
Let
ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
in
concat [replicate i x | (i, x) <- ls]
will give
"aaaabccaadeeee"
The point-free version
concat . map (uncurry replicate)
add a comment |
Let
ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
in
concat [replicate i x | (i, x) <- ls]
will give
"aaaabccaadeeee"
The point-free version
concat . map (uncurry replicate)
add a comment |
Let
ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
in
concat [replicate i x | (i, x) <- ls]
will give
"aaaabccaadeeee"
The point-free version
concat . map (uncurry replicate)
Let
ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
in
concat [replicate i x | (i, x) <- ls]
will give
"aaaabccaadeeee"
The point-free version
concat . map (uncurry replicate)
edited Nov 16 '18 at 14:09
answered Nov 16 '18 at 14:02
Elmex80sElmex80s
2,0471814
2,0471814
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%2f53329755%2fget-the-first-elements-of-a-list-of-tuples%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
1
It's usually much clearer not to work with
fst
andsnd
(and definitely not withhead
or!!
) but instead use pattern matching to get at the elements. And for doing stuff with elements of lists (be they tuples or something else), list comprehensions are syntactically very nice.– leftaroundabout
Nov 16 '18 at 0:38
2
f = (>>= uncurry replicate)
is the fancy-pants approach.– amalloy
Nov 16 '18 at 1:05
1
Your list is
ils
in[s | (n,c) <- ils, s <- replicate n c]
produces the output you require.– fp_mora
Nov 16 '18 at 2:20
map returns the array of the same size. So in this example it will give you array on strings. To do it in one operation you need fold function, which gives the accumulated result.
– Manoj R
Nov 16 '18 at 5:44