Reputation: 930
I want to get the array of doubles from a list of an array of doubles where the first value of the array is the highest value as compared to the first value of the other arrays in the list
For example, if the list of arrays are (4,5) , (-3,2) , (7,1) then it would return (7,1).
I tried this but no success:
Dim vertices as List(of Double()) = MethodToGetList()
dim rv as Double() = vertices.Select(Function(x As Double()) x.First.MaxValue).ToArray
Upvotes: 0
Views: 385
Reputation: 2153
Try this. This orders the vertices
list of arrays by the first position of each array, then by the second position of the array. Then in the case of the same data (below), the list would look like: (7,1), (7,2), ...
. Then last piece of the statement grabs the first element in the sorted list so would return (7, 1)
Dim rv As Double() = vertices.OrderByDescending(Function(v) v(0)).ThenBy(Function(v) v(1)).FirstOrDefault
Data to test:
Dim vertices As List(Of Double()) = New List(Of Double())
vertices.Add(New Double() {4, 5})
vertices.Add(New Double() {-1, 2})
vertices.Add(New Double() {7, 1})
vertices.Add(New Double() {7, 2})
Upvotes: 0
Reputation: 30454
Sorry, my basic is a bit rusty, I'll do it in C#, I hope you'll get the gist.
Whenever you want a LINQ function, where you need to examine every item of your sequence exactly once, and you want to do something with the item that is currently being examined, think of Aggregate
.
This will initialize variable highestValue with your first source element; then it will compare every source element with the highestValue and keep the one that is highest:
List<List<double>> mySource = ...
var result = mySource.Aggregate( (highestValue, nextValue) =>
(nextValue[0] > highestValue[0]) ? nextValue : highestValue);
This will be similar to:
List<double> highestValue = mySource[0];
for (int i=1; i<mySource.Count; ++i)
{
if (mySource[i][0] > higestValue[0])
{
// found a new highestValue
highestValue = mySource[i];
}
// else: keep the highest value
}
It is easy to see, that this only works if mySource
is not empty. If you have an empty source, you should think of what you want as a result. We will initialize with this emptyResult:
List<double> emptyResult = ... // what do you want to use if there is nothing in your source?
List<double> highestValue = emptyResult;
for (int i=0; i<mySource.Count; ++i)
{
if (mySource[i][0] > higestValue[0])
{
// found a new highestValue
highestValue = mySource[i];
}
}
And now in LINQ: use the other Aggregate:
var result = mySource.Aggregate(emptyResult, // use this as seeder
(nextValue[0] > highestValue[0]) ? nextValue : highestValue);
This will help if you have an empty sequence. Buf what if one of your Lists in the source is null or empty?
Let's assume you don't want to consider them at all:
var nonEmptyArrays = mySource.Where(list => list != null && list.Count != 0)
var result = noneEmptyArrays.Aggregate((emptyResult, // use this as seeder
(nextValue[0] > highestValue[0]) ? nextValue : highestValue);
Simple comme bonjour!
Upvotes: 1