Reputation: 107
Please consider a List of Tuples in C#. This relates to the original Tuple (not Value Tuple). How can I get the index of the List, if I know one of the Items within the List of Tuples?
List<Tuple<double, int>> ListOfTuples2 = new
List<Tuple<double, int>>();
double doubleTuple = 5000;
int intTuple = 7;
ListOfTuples2.Add(Tuple.Create(doubleTuple, intTuple));
ListOfTuples2.Add(Tuple.Create(5000.00, 2));
ListOfTuples2.Add(Tuple.Create(5000.25, 3));
ListOfTuples2.Add(Tuple.Create(5000.50, 4));
ListOfTuples2.Add(Tuple.Create(5000.25, 5));
/* How can I get the Index of the List if
doubleTuple = 5000.25 ? */
Upvotes: 1
Views: 3694
Reputation: 112279
You can use the FindIndex
method of the list accepting a predicate as argument
int index = ListOfTuples2.FindIndex(t => t.Item1 == 5000.25);
if (index > = 0) {
// found!
}
FindIndex
returns -1
if no such item is found.
But you might consider using a dictionary instead. If the collection is big, it finds entries much faster than a list. The retrieval times in Big O notation: List<T>
is O(n)
, Dictionary<K,V>
is O(1)
. However, items in a dictionary are not ordered and have no index. In addition, keys must be unique. If you need ordered items, stick to the list.
var dict = new Dictionary<double, int>{
[doubleTuple] = intTuple,
[5000.00] = 2,
[5000.25] = 3,
[5000.50] = 4,
[5000.25] = 5
}
if (dict.TryGetValue(5000.25, out int result)) {
// result is 3; and contains the value, not the index.
}
You can also add entries with
dict.Add(5000.75, 8);
If you are sure that the dictionary contains an entry, you can simply retrieve it with
int result = dict[5000.25];
Also, if you are dealing with prices, consider using the decimal
type. If has been created specifically for financial and monetary calculations. The double
type stores the values as binary numbers. 0.1
(decimal) is 0.000110011001100110011001100110011...
(binary), i.e., double
introduces a rounding error, solely by converting a decimal constant into its binary representation, whereas decimal
stores each decimal of the constant as is. double
is okay (and faster) for scientific calculations. It makes no difference whether a temperature is 29.7 or 29.69999999999 degrees, since you can measure it with a very limited precision anyway (maybe 1%).
C# 7.0 has added ValueTuple
types plus a simple syntax for tuple types and tuple values. Consider replacing the Tuple
class with this new feature.
var listOfValueTuples = new List<(double, int)> {
(doubleTuple, intTuple),
(5000.00, 2),
(5000.25, 3),
(5000.50, 4),
(5000.25, 5)
};
Upvotes: 9
Reputation: 4377
In case you want to get all indexes you can write following code:
var indexes = ListOfTuples2.Select((tuple, index) => new {tuple, index}).Where(o => Math.Abs(o.tuple.Item1 - 5000.25) < 1e-5).Select(o => o.index - 1);
foreach (var index in indexes)
{
Console.WriteLine(index);
}
Note that comparing two floats can return unpredictable results, so I used comparing using Math.Abs
method
Upvotes: 2