0

By efficient I mean shortest time for computation.

I came up with:

List<float> valuesLaterThanDate = new List<float>();
foreach (var kvp in sortedList.Where( t => t.Key >= selectionDate))
{           
   valuesLaterThanDate.Add( kvp.Value );
}

is there a more efficient way? Or more compact expression?

Charlieface
  • 52,284
  • 6
  • 19
  • 43
Markus
  • 1,020
  • 14
  • 18

3 Answers3

3

Yes, you can write it as a more compact expression:

var valuesLaterThanDate = sortedList.Where(t => t.Key >= selectionDate).Select(t => t.Value).ToList();
Xaver
  • 1,035
  • 9
  • 17
  • Thanks, is the resulting list guaranteed to be ordered by the original Keys for each value? – Markus May 22 '22 at 19:18
  • Yes, to the best of my knowledge, LINQ preserves the original ordering. Also see here: https://stackoverflow.com/questions/204505/preserving-order-with-linq – Xaver May 22 '22 at 19:27
  • @Charlieface: It's more compact, but it doesn't return the values. – Xaver May 22 '22 at 19:34
2

There are two performance efficiencies you can make:

  • Use IndexOfKey to perform a binary search of the starting key. This has O(log(N)) efficency.
  • You can pre-allocate the list to do a more efficient insert.
var startIndex = sortedList.IndexOfKey(selectionDate);
var valuesLaterThanDate = new List<float>(sortedList.Count - startIndex);
for (var i = startIndex; i < sortedList.Count; i++)
{
    valuesLaterThanDate.Add(sortedList[i].Value);
}

Note that IndexOfKey just returns -1 if the key is not found, so if that can happen then you may need to implement binary search yourself. There have been complaints about this issue in the past regarding SortedList<T>.

Charlieface
  • 52,284
  • 6
  • 19
  • 43
  • I want to point out that your solution only works if the key `selectionDate` is present in the original list. Of course, you kind of mention it in your last sentence, but I think this is a major drawback of your solution. – Xaver May 22 '22 at 19:40
  • Depends on your metric: more code (to implement `BinarySearch` if necessary) or more compact. I've added a link to the .NET implementation. `SortedList` is a particular bugbear, `List` does have a proper `BinarySearch` – Charlieface May 22 '22 at 19:47
0

A more efficient way? This is not answerable, as you have not laid out any the criteria to measure/determine efficiency. Performance efficiency? Memory usage efficiency? Code readability/maintainability?

A more compact form? Yes:

var valuesLaterThanDate = sortedList
    .Where(t => t.Key >= selectionDate)
    .Select(t => t.Value)
    .ToList();
Snorebert
  • 1
  • 1