Reputation: 7
Let's say I have a List<float>
with the following values:
{20, 60, 80, 85, 90, 120, 140}
And I have one number, let's suppose "75". How can I find the index where this number I have (75) is >= then an index's value and < then the next index's value? In basic words, I want to find that my number (75), is "inside" the range between 60 and 80, so it returns to me index number 1.
So far, I've used Linq but it only returns to me the nearest value. I'd like to find the Index instead.
myList.OrderBy(x => Math.Abs(points - x)).First()
Is there an efficient way to return to me this index? I know there's the possibility to use a For loop, but I believe that a loop may be heavy if I take into consideration that I may have to call this a couple of times in a few seconds. (The list will contain ~99 values).
Thank you very much! I appreciate any help!
Upvotes: 0
Views: 1504
Reputation: 18008
Actually, a for
loop will be fast. The accepted answer has an OrderBy
(has time complexity of nlogn
), but assuming your list is already sorted, and you can try this:
var myList = new List<float>{20, 60, 80, 85, 90, 120, 140};
var numberToSearch = 75;
var foundIndex = -1;
for(var i=0; i<myList.Count; i++)
{
if(myList[i] >= numberToSearch)
{
foundIndex = i;
break;
}
}
if(foundIndex<=0)
{
// Element was not found
}
else
{
// the desired range is: [foundIndex-1, foundIndex], i.e. (1,2)
}
Upvotes: 1
Reputation: 18155
I hope I understood what you meant.
Following should help you
var list = new List<float>{20, 60, 80, 85, 90, 120, 140};
var numberToSearch = 70;
var result = list.Select((x,index)=> new
{
Index=index,
Value=x,
Diff = Math.Abs(x-numberToSearch)
})
.OrderBy(x=>x.Diff)
.First()
.Index;
Console.WriteLine($"Search Term {numberToSearch}, Index={result}");
Alternatively (if the list is sorted initially), you could also do
var result = list.Select((x,index)=> new {number=x, index= index}).First(x=> x.number > numberToSearch).index - 1;
if(result == -1)
{
Console.WriteLine("Not Found");
}
else
Console.WriteLine($"Search Term {numberToSearch}, Index={result}");
}
Output for numberToSearch = 70
Search Term 70, Index=1
Output for numberToSearch = 87
Search Term 87, Index=3
Upvotes: 2
Reputation: 1423
Answer from @mshsayem is correct but much nicer code will be
var list = new List<float>{20, 60, 80, 85, 90, 120, 140};
var numberToSearch = 70;
var foundIndex = myList.FindIndex(_ => _ > numberToSearch);
if (foundIndex < 0) // not found;
if(foundIndex == 0) // found but first element
else // index foundIndex-1 and foundIndex
It will not check further elements when getting hit.
Upvotes: 0
Reputation: 1
I would try a method that looks at the first number (20), if it is not greater than 75, it puts 20 in a method and it moves onto the next number (40), since it is not greater than 75 it replaces the method that stores 20, with the number 40, then it moves onto the next number, that should happen until it reaches 80. Once it reaches 80, then It should read that 80 is greater than 75. Then take the method that stores the number before it, which would be 60, and it would put 75 in between them.
Upvotes: 0