Showing posts with label LINQ. Show all posts
Showing posts with label LINQ. Show all posts

Friday, April 24, 2020

Iterate two arrays simultaneously with one foreach statement in C#


Let’s say that you have two lists or two arrays that you wish to combine.  One has a list of first names, the other a list of last names.  The list items are in the correct order so that the first name would match the last name for a given ordinal number.  But the lists may not have the same lengths (i.e. one list is not as complete as the other).  We wish to match all of the available first and last names until we run out of matching pairs.

So, what do we do?

For two arrays, we could use a “for int” loop.  We could get the size of each array by calling its Length property. And then we can compare which length is smaller; and use that number as our loop’s upper boundary.  We could then use the indexer to refer to each element in turn.  But this solution is rather inelegant.

For two lists, we should not use a “for int” loop, since lists do not have the concept of indexers.  We cannot refer to individual elements of the list via an index.  We can instead use a “foreach” loop.  But how do you refer to corresponding elements from 2 lists with each loop iteration?

This is where the Linq’s Zip method comes in very handy.  With the Zip method, we can apply a specific function to the corresponding elements of two sequences and produce a sequence of the results.

Using the above scenario as an example, where we have 5 first names but only 4 last names, we can write the following code:


The Output is below.

You will notice that the Zip function stopped after its 4th iteration.  In this way, we don’t have any incomplete names.

That’s it for now.  I hope this tip has been super helpful.



Saturday, January 11, 2014

Selecting Top n Rows from a Data Table


Let’s say that you wish to display rows of customer reviews and other pertinent info on your web page.  Unless you are okay with the ugly default format of a GridView control, you will probably want to use a Repeater control.  You will, of course, bind the Repeater control to a data source.  And that data source will probably be a resulset table from a stored procedure.

Reviews can take up a lot of real estate, though.  So let’s say that you wish to limit the number of reviews that show up initially on the page.  You will provide a “Show More” button or a pagination control to allow the user to see more reviews, as they desire.

In other words, you want a simple way to select the top n rows from a data table.  Before the arrival of the .Net Framework 3.5 and LINQ, you would have had to write a number of lines of code to implement this functionality.  With LINQ, however, you can be down to one line.

The code would look something like below:
Int pageSize = 10;
repeaterReviews.DataSource = reviewsDataTable.AsEnumerable().Take(pageSize).ToList();
repeaterReviews.DataBind();

The code looks like it makes a lot of sense, and that it should work.  But wait – in fact it does not work.  The data source that you bind to the repeater control should be of type DataTable, which an IEnumerable of List is not.  To make this work, we will need to convert the List back to a DataTable.  We do that by using the CopyToDataTable extension method of enumerable types.

Thus our final code should look like below:
Int pageSize = 10;
repeaterReviews.DataSource = reviewsDataTable.AsEnumerable().Take(pageSize).CopyToDataTable();
repeaterReviews.DataBind();

Happy programming!