hallibut
hallibut

Reputation: 270

Call Length Property on Returned Array in Chained String/LINQ Methods of C#

I found this post on selecting a range from an array, and have to use the LINQ option:

Selecting a range of items inside an array in C#

Ultimately, I'm trying to get the last four lines from some text file. After, I've read in and cleaned the lines for unwanted characters and empty lines, I have an array with all of the lines. I'm using the following to do so:

string[] allLines = GetEachLine(results);
string[] lastFourLines = allLines.Skip(allLines.Length - 4).Take(4).ToArray();

This works fine, but I'm wondering if I could somehow skip assinging to the allLines variable all together. Such as:

string[] lastFourLines = GetEachLine(results).Skip(returnedArrayLength - 4).Take(4).ToArray();

Upvotes: 0

Views: 93

Answers (3)

NetMage
NetMage

Reputation: 26936

It would be better to change GetEachLine and code preceding it (however results is computed) to use IEnumerable<T> and avoid using an array to read the entire file in memory for the last four lines (unless you use all of results for something else) - consider using File.ReadLines.

However, if you are using .Net Core 2.0 or greater, you can use Enumerable.TakeLast to efficiently return the last four lines:

var lastFourLines = GetEachLine(results).TakeLast(4);

Upvotes: 2

DCAggie
DCAggie

Reputation: 166

if GetEachLine() returns string[] then that should work fine, though null checking may be needed.

As you chain more you may want to use line breaks to increase readability:

string[] lastFourLines = GetEachLine(results)
    .Skip(allLines.Length - 4)
    .Take(4)
    .ToArray();

allLines.Length won't exist unless you still have line 1 from your question, you can avoid calling GetEachLine() twice by using TakeLast().

string[] lastFourLines = GetEachLine(results)
    .TakeLast(4)
    .ToArray();

Upvotes: 1

T N
T N

Reputation: 10204

If you are looking to efficiently retrieve the last N (filtered) line of a large file, you really need to start at the point where you are reading the file contents.

Consider a 1GB log file containing 10M records, where you only want the last few lines. Ideally, you would want to start by reading the last couple KB and then start extracting lines by searching for line breaks from the end, extracting each line and returning them in an iterator yield. If you run out of data, read the preceding block. Continue only as long as the consumer requests more values from the iterator.

Offhand, I don't know a built-in way to do this, and coding this from scratch could get pretty involved. Luckily, a search turned up this similar question having a highly rated answer.

Upvotes: 0

Related Questions