I am currently stuck on evaluating a list of some Double
s representing time intervals. Let's say I have an unordered list of up to 100 values fluctuating around 1: [0.897, 0.912, ... 1.214, 0.981]
I am now trying to find the interval of 0.05s
that includes the most values in my list (say 20 of a list with 100 values).
Below is what I came up on my own and although it seems to work on my dummy data, this approach (looping the entire list for every interval) appears really redundant to me, especially if I were to evaluate much larger lists.
I am interested if someone could advice a more elegant way, perhaps using plotting of some sort? ´´´
var lowerEnd = 0.5
var higherEnd = 1.5
var numberOfElements = 0
var currentMost = 0
var mostCommonRange = 0.0
while(lowerEnd < higherEnd) {
records.forEach { entry ->
if(lowerEnd <= entry && entry < (lowerEnd + 0.05)) {
numberOfElements += 1
}
}
if(numberOfElements > currentMost) {
currentMost = numberOfElements
mostCommonRange = lowerEnd
}
numberOfElements = 0
lowerEnd += .05
}
´´´
I am currently stuck on evaluating a list of some Double
s representing time intervals. Let's say I have an unordered list of up to 100 values fluctuating around 1: [0.897, 0.912, ... 1.214, 0.981]
I am now trying to find the interval of 0.05s
that includes the most values in my list (say 20 of a list with 100 values).
Below is what I came up on my own and although it seems to work on my dummy data, this approach (looping the entire list for every interval) appears really redundant to me, especially if I were to evaluate much larger lists.
I am interested if someone could advice a more elegant way, perhaps using plotting of some sort? ´´´
var lowerEnd = 0.5
var higherEnd = 1.5
var numberOfElements = 0
var currentMost = 0
var mostCommonRange = 0.0
while(lowerEnd < higherEnd) {
records.forEach { entry ->
if(lowerEnd <= entry && entry < (lowerEnd + 0.05)) {
numberOfElements += 1
}
}
if(numberOfElements > currentMost) {
currentMost = numberOfElements
mostCommonRange = lowerEnd
}
numberOfElements = 0
lowerEnd += .05
}
´´´
Share Improve this question asked Mar 27 at 1:57 AlexAlex 711 silver badge9 bronze badges 2- 2 Are you only trying to chose between intervals that start every 0.05 then? Ie [0.5, 0.55], [0.55, 0.6],... Presumably [0.56, 0.61] is not a valid answer? – Simon Jacobs Commented Mar 27 at 2:22
- Yes you're right. I wasn't specific in my question. – Alex Commented Mar 27 at 12:20
1 Answer
Reset to default 3Since you only consider ranges that start and end at multiples of 0.05 (and not e.g. 0.01 ~ 0.06), just doing (x / 0.05).toInt()
will tell you which range a number x
is in.
So you just group by (x / 0.05).toInt()
, and count how many items are in each group, then find the biggest group.
fun rangeLowerBound(list: List<Double>) =
list.groupingBy { (it / 0.05).toInt() }.eachCount().maxBy { it.value }.key * 0.05
rangeLowerBound(listOf(-0.1, -0.11, -0.13, 0.1, 0.11, 0.12, 0.13))
will return 0.1, meaning that the range 0.1 ~ 0.15 contains the most numbers out of all the other ranges.
Note that this assumes the list is non-empty. If the list can be empty, you can use .maxByOrNull { it.value }?.key?.times(0.05)
and return that (which would be null if the list is empty), or provide a default value with ?:
.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744116852a4559215.html
评论列表(0条)