Choosing x number of elements from System.Collections.Generic.List C #

I need a way to select the last 100 items from a list, as a list

public List<Model.PIP> GetPIPList() { if (Repository.PIPRepository.PIPList == null) Repository.PIPRepository.Load(); return Repository.PIPRepository.PIPList.Take(100); } 

I get an error like this

'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.List'. Explicit conversion exists (are you skipping listing?)

+4
source share
5 answers

If your list is large, you will get maximum performance by copying your own:

 public static class ListExtensions { public static IEnumerable<T> LastItems<T>(this IList<T> list, int numberOfItems) //Can also handle arrays { for (int index = Math.Max(list.Count - numberOfItems, 0); index < list.Count; index++) yield return list[index]; } } 

Why is this faster than using Skip ()? If you have a list of 50,000 items, Skip () calls MoveNext () on the enumerator 49,900 times before it starts returning items.

Why is this faster than using the reverse () function? Because Reverse selects a new array large enough to hold the list items and copies them to the array. This is especially good to avoid if the array is large enough to jump to a bunch of large objects.

+4
source
 somelist.Reverse().Take(100).Reverse().ToList(); 

It would be much cheaper than ordering :) Also keeps the original order.

+9
source

EDIT: I missed what you said you want the last 100 items, and haven’t been able to do it yet.

To get the last 100 items:

 return Repository.PIPRepository.PIPList .OrderByDescending(pip=>pip.??).Take(100) .OrderBy(pip=>pip.??); 

... and then change your method signature to return IEnumerable<Model.PIP>

?? means which property you would sort.

Joel also gives an excellent solution based on counting the number of elements in the last and skipping all but 100 of them. In many cases, this probably works better. I did not want to publish the same solution in my editing! :)

+4
source

Try:

 public List<Model.PIP> GetPIPList() { if (Repository.PIPRepository.PIPList == null) Repository.PIPRepository.Load(); return Repository.PIPRepository.PIPList.Take(100).ToList(); } 
+2
source

Returns the .Take() method and IEnumerable<T> , not List<T> . This is good, and you should seriously consider changing your method and your work habits to use IEnumerable<T> rather than List<T> as much as possible.

In addition, .Take(100) will also return the first 100 elements, not the last 100 elements. You want something like this:

 public IEnumerable<Model.PIP> GetPIPs() { if (Repository.PIPRepository.PIPList == null) Repository.PIPRepository.Load(); return Repository.PIPRepository.PIPList.Skip(Math.Max(0,Repository.PIPRepository.PIPList.Count - 100)); } 

If you really need a list rather than an enumerable (hint: you probably aren't), it's even better to create this method with IEnumerable and use .ToList() at the place where you call this method.

At some point in the future you will want to come back and update your Load () code to use IEnumerable as well as the code in the future. The ultimate goal here is to get to the point that you efficiently transfer your objects to the browser, and only one of them is loaded into memory on your web server at a time. IEnumerable allows this. Not listed.

+2
source

Source: https://habr.com/ru/post/1379592/


All Articles