Count how many times numbers from a list occur in a list of tupled intervals in Scala
Say I have a list of tuples:
val ranges= List((1,4), (5,8), (9,10))
and a list of numbers
val nums = List(2,2,3,7,8,9)
I want to make a map from tuple in ranges to how many times a given number from nums fall into the interval of that tuple.
Output:
Map ((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
What is the best way to go about it in Scala
I have been trying to use for loops and keeping a counter but am falling short. Any help would be very much appreciated.
Best Regards
scala tuples accumulator
add a comment |
Say I have a list of tuples:
val ranges= List((1,4), (5,8), (9,10))
and a list of numbers
val nums = List(2,2,3,7,8,9)
I want to make a map from tuple in ranges to how many times a given number from nums fall into the interval of that tuple.
Output:
Map ((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
What is the best way to go about it in Scala
I have been trying to use for loops and keeping a counter but am falling short. Any help would be very much appreciated.
Best Regards
scala tuples accumulator
add a comment |
Say I have a list of tuples:
val ranges= List((1,4), (5,8), (9,10))
and a list of numbers
val nums = List(2,2,3,7,8,9)
I want to make a map from tuple in ranges to how many times a given number from nums fall into the interval of that tuple.
Output:
Map ((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
What is the best way to go about it in Scala
I have been trying to use for loops and keeping a counter but am falling short. Any help would be very much appreciated.
Best Regards
scala tuples accumulator
Say I have a list of tuples:
val ranges= List((1,4), (5,8), (9,10))
and a list of numbers
val nums = List(2,2,3,7,8,9)
I want to make a map from tuple in ranges to how many times a given number from nums fall into the interval of that tuple.
Output:
Map ((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
What is the best way to go about it in Scala
I have been trying to use for loops and keeping a counter but am falling short. Any help would be very much appreciated.
Best Regards
scala tuples accumulator
scala tuples accumulator
asked Jan 18 at 14:19
Arun ShyamArun Shyam
2251417
2251417
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Something like this:
val ranges = List((1, 4), (5, 8), (9, 10))
val nums = List(2, 2, 3, 7, 8, 9)
val occurences = ranges.map { case (l, r) => nums.count((l to r) contains _) }
val map = (ranges zip occurences).toMap
println(map) // Map((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
Basically it first calculates the number of occurrences, [3, 2, 1]. From there it's easy to construct a map. And the way it calculates the occurrences is:
- go through the list of ranges
- transform each range into number of occurrences for that range, which is done like this :
- how many numbers from the list
nums
are contained in that range?
- how many numbers from the list
EDIT: Not sure why this answer is getting downvoted, perhaps I misunderstood the question somehow.
3
I don't know who downvoted you, it's the good answer and very scala-ish.
– Etienne Herlaut
Jan 18 at 14:58
No you didn’t misunderstand it, I believe on a large (l, r) range, contains can be a bottleneck. But I corrected for that myself 👍🏽. This was definitely right
– Arun Shyam
Jan 18 at 20:19
@Arun Shyam Yes this is inefficient, but I wanted to point you in the direction of thinking about the solution in a different way. BTW if you get a question like this on something like HackerRank, it might even be outside of time constraints and you would in that case be forced to an iterative approach with loops and counters. But whenever I can, I prefer FP solutions.
– slouc
Jan 19 at 14:51
add a comment |
Here is an efficient single-pass solution:
ranges
.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))
.toMap
This avoids the overhead of creating a list of numbers and then zipping them with the ranges in a separate step.
This is a version that uses more Scala features but is a bit too fancy:
(for {
r <- ranges
range = r._1 to r._2
} yield r -> nums.count(range.contains)
).toMap
This is also less efficient because contains
has to allow for ranges with a step value and is therefore more complicated.
And here is an even more efficient version that avoids any temporary data structures:
val result: Map[(Int, Int), Int] =
ranges.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))(collection.breakOut)
See this explanation of breakOut
if you are not familiar with it. Using breakOut
means that the map
call will build the Map
directly rather than creating a List
that has to be converted to a Map
using toMap
.
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%2f54255882%2fcount-how-many-times-numbers-from-a-list-occur-in-a-list-of-tupled-intervals-in%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Something like this:
val ranges = List((1, 4), (5, 8), (9, 10))
val nums = List(2, 2, 3, 7, 8, 9)
val occurences = ranges.map { case (l, r) => nums.count((l to r) contains _) }
val map = (ranges zip occurences).toMap
println(map) // Map((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
Basically it first calculates the number of occurrences, [3, 2, 1]. From there it's easy to construct a map. And the way it calculates the occurrences is:
- go through the list of ranges
- transform each range into number of occurrences for that range, which is done like this :
- how many numbers from the list
nums
are contained in that range?
- how many numbers from the list
EDIT: Not sure why this answer is getting downvoted, perhaps I misunderstood the question somehow.
3
I don't know who downvoted you, it's the good answer and very scala-ish.
– Etienne Herlaut
Jan 18 at 14:58
No you didn’t misunderstand it, I believe on a large (l, r) range, contains can be a bottleneck. But I corrected for that myself 👍🏽. This was definitely right
– Arun Shyam
Jan 18 at 20:19
@Arun Shyam Yes this is inefficient, but I wanted to point you in the direction of thinking about the solution in a different way. BTW if you get a question like this on something like HackerRank, it might even be outside of time constraints and you would in that case be forced to an iterative approach with loops and counters. But whenever I can, I prefer FP solutions.
– slouc
Jan 19 at 14:51
add a comment |
Something like this:
val ranges = List((1, 4), (5, 8), (9, 10))
val nums = List(2, 2, 3, 7, 8, 9)
val occurences = ranges.map { case (l, r) => nums.count((l to r) contains _) }
val map = (ranges zip occurences).toMap
println(map) // Map((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
Basically it first calculates the number of occurrences, [3, 2, 1]. From there it's easy to construct a map. And the way it calculates the occurrences is:
- go through the list of ranges
- transform each range into number of occurrences for that range, which is done like this :
- how many numbers from the list
nums
are contained in that range?
- how many numbers from the list
EDIT: Not sure why this answer is getting downvoted, perhaps I misunderstood the question somehow.
3
I don't know who downvoted you, it's the good answer and very scala-ish.
– Etienne Herlaut
Jan 18 at 14:58
No you didn’t misunderstand it, I believe on a large (l, r) range, contains can be a bottleneck. But I corrected for that myself 👍🏽. This was definitely right
– Arun Shyam
Jan 18 at 20:19
@Arun Shyam Yes this is inefficient, but I wanted to point you in the direction of thinking about the solution in a different way. BTW if you get a question like this on something like HackerRank, it might even be outside of time constraints and you would in that case be forced to an iterative approach with loops and counters. But whenever I can, I prefer FP solutions.
– slouc
Jan 19 at 14:51
add a comment |
Something like this:
val ranges = List((1, 4), (5, 8), (9, 10))
val nums = List(2, 2, 3, 7, 8, 9)
val occurences = ranges.map { case (l, r) => nums.count((l to r) contains _) }
val map = (ranges zip occurences).toMap
println(map) // Map((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
Basically it first calculates the number of occurrences, [3, 2, 1]. From there it's easy to construct a map. And the way it calculates the occurrences is:
- go through the list of ranges
- transform each range into number of occurrences for that range, which is done like this :
- how many numbers from the list
nums
are contained in that range?
- how many numbers from the list
EDIT: Not sure why this answer is getting downvoted, perhaps I misunderstood the question somehow.
Something like this:
val ranges = List((1, 4), (5, 8), (9, 10))
val nums = List(2, 2, 3, 7, 8, 9)
val occurences = ranges.map { case (l, r) => nums.count((l to r) contains _) }
val map = (ranges zip occurences).toMap
println(map) // Map((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)
Basically it first calculates the number of occurrences, [3, 2, 1]. From there it's easy to construct a map. And the way it calculates the occurrences is:
- go through the list of ranges
- transform each range into number of occurrences for that range, which is done like this :
- how many numbers from the list
nums
are contained in that range?
- how many numbers from the list
EDIT: Not sure why this answer is getting downvoted, perhaps I misunderstood the question somehow.
edited Jan 18 at 15:01
answered Jan 18 at 14:43
sloucslouc
5,6062729
5,6062729
3
I don't know who downvoted you, it's the good answer and very scala-ish.
– Etienne Herlaut
Jan 18 at 14:58
No you didn’t misunderstand it, I believe on a large (l, r) range, contains can be a bottleneck. But I corrected for that myself 👍🏽. This was definitely right
– Arun Shyam
Jan 18 at 20:19
@Arun Shyam Yes this is inefficient, but I wanted to point you in the direction of thinking about the solution in a different way. BTW if you get a question like this on something like HackerRank, it might even be outside of time constraints and you would in that case be forced to an iterative approach with loops and counters. But whenever I can, I prefer FP solutions.
– slouc
Jan 19 at 14:51
add a comment |
3
I don't know who downvoted you, it's the good answer and very scala-ish.
– Etienne Herlaut
Jan 18 at 14:58
No you didn’t misunderstand it, I believe on a large (l, r) range, contains can be a bottleneck. But I corrected for that myself 👍🏽. This was definitely right
– Arun Shyam
Jan 18 at 20:19
@Arun Shyam Yes this is inefficient, but I wanted to point you in the direction of thinking about the solution in a different way. BTW if you get a question like this on something like HackerRank, it might even be outside of time constraints and you would in that case be forced to an iterative approach with loops and counters. But whenever I can, I prefer FP solutions.
– slouc
Jan 19 at 14:51
3
3
I don't know who downvoted you, it's the good answer and very scala-ish.
– Etienne Herlaut
Jan 18 at 14:58
I don't know who downvoted you, it's the good answer and very scala-ish.
– Etienne Herlaut
Jan 18 at 14:58
No you didn’t misunderstand it, I believe on a large (l, r) range, contains can be a bottleneck. But I corrected for that myself 👍🏽. This was definitely right
– Arun Shyam
Jan 18 at 20:19
No you didn’t misunderstand it, I believe on a large (l, r) range, contains can be a bottleneck. But I corrected for that myself 👍🏽. This was definitely right
– Arun Shyam
Jan 18 at 20:19
@Arun Shyam Yes this is inefficient, but I wanted to point you in the direction of thinking about the solution in a different way. BTW if you get a question like this on something like HackerRank, it might even be outside of time constraints and you would in that case be forced to an iterative approach with loops and counters. But whenever I can, I prefer FP solutions.
– slouc
Jan 19 at 14:51
@Arun Shyam Yes this is inefficient, but I wanted to point you in the direction of thinking about the solution in a different way. BTW if you get a question like this on something like HackerRank, it might even be outside of time constraints and you would in that case be forced to an iterative approach with loops and counters. But whenever I can, I prefer FP solutions.
– slouc
Jan 19 at 14:51
add a comment |
Here is an efficient single-pass solution:
ranges
.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))
.toMap
This avoids the overhead of creating a list of numbers and then zipping them with the ranges in a separate step.
This is a version that uses more Scala features but is a bit too fancy:
(for {
r <- ranges
range = r._1 to r._2
} yield r -> nums.count(range.contains)
).toMap
This is also less efficient because contains
has to allow for ranges with a step value and is therefore more complicated.
And here is an even more efficient version that avoids any temporary data structures:
val result: Map[(Int, Int), Int] =
ranges.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))(collection.breakOut)
See this explanation of breakOut
if you are not familiar with it. Using breakOut
means that the map
call will build the Map
directly rather than creating a List
that has to be converted to a Map
using toMap
.
add a comment |
Here is an efficient single-pass solution:
ranges
.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))
.toMap
This avoids the overhead of creating a list of numbers and then zipping them with the ranges in a separate step.
This is a version that uses more Scala features but is a bit too fancy:
(for {
r <- ranges
range = r._1 to r._2
} yield r -> nums.count(range.contains)
).toMap
This is also less efficient because contains
has to allow for ranges with a step value and is therefore more complicated.
And here is an even more efficient version that avoids any temporary data structures:
val result: Map[(Int, Int), Int] =
ranges.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))(collection.breakOut)
See this explanation of breakOut
if you are not familiar with it. Using breakOut
means that the map
call will build the Map
directly rather than creating a List
that has to be converted to a Map
using toMap
.
add a comment |
Here is an efficient single-pass solution:
ranges
.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))
.toMap
This avoids the overhead of creating a list of numbers and then zipping them with the ranges in a separate step.
This is a version that uses more Scala features but is a bit too fancy:
(for {
r <- ranges
range = r._1 to r._2
} yield r -> nums.count(range.contains)
).toMap
This is also less efficient because contains
has to allow for ranges with a step value and is therefore more complicated.
And here is an even more efficient version that avoids any temporary data structures:
val result: Map[(Int, Int), Int] =
ranges.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))(collection.breakOut)
See this explanation of breakOut
if you are not familiar with it. Using breakOut
means that the map
call will build the Map
directly rather than creating a List
that has to be converted to a Map
using toMap
.
Here is an efficient single-pass solution:
ranges
.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))
.toMap
This avoids the overhead of creating a list of numbers and then zipping them with the ranges in a separate step.
This is a version that uses more Scala features but is a bit too fancy:
(for {
r <- ranges
range = r._1 to r._2
} yield r -> nums.count(range.contains)
).toMap
This is also less efficient because contains
has to allow for ranges with a step value and is therefore more complicated.
And here is an even more efficient version that avoids any temporary data structures:
val result: Map[(Int, Int), Int] =
ranges.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))(collection.breakOut)
See this explanation of breakOut
if you are not familiar with it. Using breakOut
means that the map
call will build the Map
directly rather than creating a List
that has to be converted to a Map
using toMap
.
edited Jan 19 at 12:21
answered Jan 18 at 15:09
TimTim
5,0791317
5,0791317
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%2f54255882%2fcount-how-many-times-numbers-from-a-list-occur-in-a-list-of-tupled-intervals-in%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