2

I have a List<List<string>> and need to filter the inner List. It looks like this:

{["/DownloadFile2.aspx?File=1026704PR20131001.PDF","10/1/2013 | Monthly Memo","10/1/2013","","","CI","","","","","",""],
 ["/DownloadFile2.aspx?File=1026704PR20141001.PDF","10/1/2014 | Monthly Memo","10/1/2014","","","CC","","","","","",""],
 ["/DownloadFile2.aspx?File=1026704date20130928.PDF","9/30/2013 | New Memo","9/30/2013","","","CC","","","","","",""],
 ["/DownloadFile2.aspx?File=1026704date20140928.PDF","9/30/2014 | New Memo","9/30/2014","","","CI","","","","","",""]}

How would I filter the second column using a LINQ .Where clause?

Like filtering on the term "Monthly" would return:

{["/DownloadFile2.aspx?File=1026704PR20131001.PDF","10/1/2013 | Monthly Memo","10/1/2013","","","CI","","","","","",""],
 ["/DownloadFile2.aspx?File=1026704PR20141001.PDF","10/1/2014 | Monthly Memo","10/1/2014","","","CC","","","","","",""]}

Adding Code

Archive Definition from my web service:

[DataContract(Namespace = "http://www.mysite.com")]
public class Archive
{
    [DataMember]
    public List<string> Header {get; set;}

    [DataMember]
    public List<List<string>> Rows{get; set;}
}

Code geting the Archive from the service (mps is the web service)

/// param contains values used to retrieve a partial set
/// as well as other values used to pass data to jQuery DataTable
///
Archive docs = mps.GetArchiveArray(LogonTicket, PID, param.iDisplayStart, param.iDisplayLength, "D");

List<List<string>> filteredRows;

// If the params sSearch value is not null or empty, filter the results
// else return the full results
if (!string.IsNullOrEmpty(param.sSearch))
{
    // Here's where I need to filter the result set based on the params.sSeach value.
    filteredRows = docs.Rows.?????;
}
else
{
    filteredRows = docs.Rows;
}

The filteredRows are then passed through a loop to build my JSON using a StringBuilder and then the full desired result is sent as JSON:

string result =  sb.ToString();
return Json(new
{
    sEcho = param.sEcho,
    iTotalRecords = numDocs,
    iTotalDisplayRecords = numDocs,
    aaData = result
},
JsonRequestBehavior.AllowGet);

3 Answers 3

3

Use the Select clause on the outer list, so something like:

outerList.Select(inr => inr.Where(...))
Sign up to request clarification or add additional context in comments.

3 Comments

filteredRows = Rows.Select(inr => inr.Where(inr[1].Contains(param.sSearch))); produces 'System.Collections.Generic.List<string>' does not contain a definition for 'Where' and the best extension method overload 'System.Linq.Enumerable.Where<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,int,bool>)' has some invalid arguments
@MB34, the where requires a Func<T, bool> parameter, typically in the form of a lambda expression. Your statement should be written as filterRows = Rows.Select(inr => inr.Where(x => x[1].Contains(...)));
filteredRows = Docs.Rows.Select(inr => inr.Where(x => x[1].Contains(param.sSearch))); shows error "'char' does not contain a definition for 'Contains'". Besides, isn't using x[1] searching only the second column?
3
var lists = ...;
var filteredLists = (from list in lists
                     where list[1].EndsWith(" | Monthly Memo")
                     select list).ToList();

Or if it is only that it contains Monthly then

var lists = ...;
var filteredLists = (from list in lists
                     where list[1].Contains("Monthly")
                     select list).ToList();

Or lower/upper case doesn't matter then

var lists = ...;
var filteredLists = (from list in lists
                     where list[1].ToLower().Contains("monthly")
                     select list).ToList();

When introducing ToList the lambda syntax may be clearer:

var filteredLists = lists.Where(list => list[1].Contains("Monthly"))
                         .ToList()

EDIT If you want to check all columns:

var filteredLists = lists.Where(list => list.Any(s => s.Contains("Monthly")))
                         .ToList()

7 Comments

See above, however, it should have been fairly evident.
And what result did you get? What "didn't work" for you?
Both showed this error: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Collections.Generic.List<string>>' to 'System.Collections.Generic.List<System.Collections.Generic.List<string>>'. An explicit conversion exists (are you missing a cast?) when called like this: filteredRows = from list in docs.Rows where list[1].Contains("Monthly") select list;
I cannot just search the second column, that's what the list[1] is, correct? I need to search all columns.
See updated answer. Next time you ask a question, try to be more precise or provide more examples.
|
0

Use this (it works):

var listsWithMonthly = listOfLists.Where(x => x.Any(subx => subx.Contains("Monthly"))).ToList();

For filtering just on the second column in the inner list, this works too:

var listsWithMonthly = listOfLists.Where(x => x[1].Contains("Monthly")).ToList();

8 Comments

I first thought if this as well, but it seems that the OP wants the result to be the complete list and not just that one string element. This will select just the strings that contains Monthly, not the whole lists.
How to make the first one case-insensitive?
@MB34 var listsWithMonthly = listOfLists.Where(x => x.Any(subx => subx.ToLower().Contains("monthly"))).ToList(); should work
I thought I already tried that. Anyway Here's results: System.NullReferenceException was unhandled by user code Message=Object reference not set to an instance of an object. On this line: filteredRows = docs.Rows.Where(x => x.Any(subx => subx.ToLower().Contains(param.sSearch))).ToList(); Apparently subx is null.
Then you would do something like this: filteredRows = docs.Rows.Where(x => x.Any(subx => (subx ?? string.Empty).ToLower().Contains(param.sSearch))).ToList();. Defaulting the string to string.Empty if it is null ??, will avoid the exception.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.