简体   繁体   中英

Remove lines from List<String[]> using Linq, if meeting a certain criteria

I've searched around for a solution to this question but can't find an applicable circumstance and can't get my head around it either.

I've got a List<String[]> object (a parsed CSV file) and want to remove any rows if the first value in the row is equal to my criteria.

I've tried the following (with variations) and can't seem to get it to delete the lines, it just passes over them:

rows.RemoveAll(s => s[0].ToString() != "Test");

Which I'm currently reading as, remove s if s[0] (the first value in the row) does not equal "Test".

Can someone point me in the right direction for this?

Thanks, Al.

Edit for wider context / better understanding:

The code is as follows:

  private void CleanUpCSV(string path)
    {

        List<string[]> rows = File.ReadAllLines(path).Select(x => x.Split(',')).ToList();
        rows.RemoveAll(s => s[0] != "Test");

        using (StreamWriter writer = new StreamWriter(path, false))
        {
            foreach (var row in rows)
            {
                writer.WriteLine(row);
            }
        }
    }

So the question is -> Why won't this remove the lines that do not start with "Test" and upon writing, why is it returning System.String[] as all the values?

Did you try with Where ? Where is going to filter based on a predicate. You should be able to do something like this:

Demo: Try it online!

    List<string[]> rows = new List<string[]> { new []{"Test"}, new []{ "Foo"} };
    rows = rows.Where(s => s[0] == "Test").ToList();

    foreach(var row in rows)
    {
        Console.WriteLine(string.Join(",", row));   
    }

output

Test
  • You dont need ToString() because S[0] is already a string
  • You may want to handle empty case or s[0] could throw
  • You can use s.First() instead of s[0]
  • You can learn more about Predicate on msdn

Edit

For your example:

private void CleanUpCSV(string path)
{

    var rows = File.ReadAllLines(path).Select(x => x.Split(','));

    using (StreamWriter writer = new StreamWriter(path, false))
    {
        foreach (var row in rows.Where(s => s[0] == "Test"))
        {
            writer.WriteLine(string.Join(",", row));
        }
    }
}

By the way, you may want to use a library to handle csv parsing. I personally use CsvHelper

The only error in your code is the following:

Since row is string[] this

writer.WriteLine(row);

won't give you the result you were expecting.

Change it like this

writer.WriteLine(String.Join(",", row));

To convert the string[] back into its orginal form.

Any other "optimisation" in all the answers proposed here arent really optimal either.

If you're really trying to remove items where the first element isn't "Test", then your code should work, though you don't need to call .ToString() on s[0] since it's already a string. If this doesn't work for you, perhaps your problem lurks elsewhere? If you give an example of your code in a wider context you could get more help

像这样过滤它:

var filteredList = rows.Where(s => s[0] == "test").ToArray();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM