Фильтровать данные, если столбец содержит один из элементов в массиве - PullRequest
0 голосов
/ 30 января 2020

У меня есть DataTable, подобный этому

ColA  ColB
1     OneThree
2     FourTwo
3     EightNine
4     ThreeEightFive
5     SevenNine

, а подстроки находятся в другом массиве ("Two","Eight", "Three")

Как отфильтровать DataTable, используя ColB, и получить строки, содержащие любая из подстрок в массиве? В массиве может быть n подстрок.

Существует ли возможный способ использования Linq без зацикливания каждого элемента массива и проверки colB с помощью ключевого слова CONTAINS?

Ответы [ 3 ]

1 голос
/ 30 января 2020

Это вернет все ColB значения, которые содержат значения из вашего списка.

var dt = // your datatable
var list = new List<string>{ "Two", "Eight", "Three" }; 
var matches = dt.AsEnumerable()
                .Where(dr => list.Any(l => dr.Field<string>("ColB").Contains(l)))
                .Select(r => r.Field<string>("ColB"))
                .ToList();

Обратите внимание, что Linq все еще выполняет закулисные циклы. Это может быть не очень эффективно (из-за Where/Any), особенно для больших наборов данных.

Если вы хотите вернуть DataTable, используйте CopyToDataTable():

var matches = dt.AsEnumerable()
                .Where(dr => list.Any(l => dr.Field<string>("ColB").Contains(l)))
                .CopyToDataTable();
1 голос
/ 30 января 2020

вы можете использовать LINQ, как показано ниже, для запроса данных

DataTable dt = new DataTable();
            dt.Columns.Add("ColA", typeof(int));
            dt.Columns.Add("ColB", typeof(string));
            dt.AcceptChanges();

            var r1 = dt.NewRow();
            r1["ColA"] = 1;
            r1["ColB"] = "OneThree";
            dt.Rows.Add(r1);

            var r2 = dt.NewRow();
            r2["ColA"] = 2;
            r2["ColB"] = "FourTwo";
            dt.Rows.Add(r2);

            var r3 = dt.NewRow();
            r3["ColA"] = 3;
            r3["ColB"] = "EightNine";
            dt.Rows.Add(r3);

            var r4 = dt.NewRow();
            r4["ColA"] = 4;
            r4["ColB"] = "ThreeEightFive";
            dt.Rows.Add(r4);

            var r5 = dt.NewRow();
            r5["ColA"] = 5;
            r5["ColB"] = "SevenNine";
            dt.Rows.Add(r5);

            dt.AcceptChanges();

            var subArray = new string[3] { "Two", "Eight", "Three" };

            var query = from r in dt.AsEnumerable()
                        where  subArray.Any(s=> r.Field<string>("ColB").IndexOf(s,StringComparison.InvariantCultureIgnoreCase)>-1)
                        select r.Field<string>("ColB");
            foreach (var item in query)
            {
                Console.WriteLine(item);
            }
0 голосов
/ 30 января 2020

Если я хорошо понимаю, тебе нужно что-то подобное. Измените MyDataTable на ваш заполненный DataTable и работайте над кодом, следуя вашим потребностям.

Dim containsMyWords As Func(Of String, Boolean) = Function(entryS As String)
                                                      Dim myWords() As String = {"r1", "r2", "r3", "r4", "r5", "r6"}
                                                      If myWords.Contains(entryS) Then Return True
                                                      Return False
                                                  End Function

Dim listRows = From dtR As DataRow In MyDataTable.AsEnumerable
               Where containsMyWords(CType(dtR.Item("ColB"), String))

For Each mRow In listRows
    Console.WriteLine(Join(mRow.ItemArray, "~"))
Next
...