Как использовать LINQ Contains (строка []) вместо Contains (строка) - PullRequest
85 голосов
/ 12 октября 2008

У меня один большой вопрос.

Я получил запрос linq, чтобы он выглядел просто так:

from xx in table
where xx.uid.ToString().Contains(string[])
select xx

Значения массива string[] будут такими числами, как (1,45,20,10 и т. Д.)

Значение по умолчанию для .Contains равно .Contains(string).

Мне нужно сделать это вместо этого: .Contains(string[]) ...

РЕДАКТИРОВАТЬ: Один пользователь предложил написать класс расширения для string[]. Я хотел бы узнать, как, но кто-нибудь готов указать мне в правильном направлении?

РЕДАКТИРОВАТЬ: UID также будет число. Вот почему он преобразуется в строку.

Помогите кому-нибудь?

Ответы [ 21 ]

76 голосов
/ 12 октября 2008

у Спулсона это почти правильно, но сначала вам нужно создать List<string> из string[]. На самом деле List<int> было бы лучше, если бы uid также int. List<T> поддерживает Contains(). Выполнение uid.ToString().Contains(string[]) будет означать, что uid как строка содержит все значения массива как подстроку ??? Даже если бы вы написали метод расширения, смысл его был бы неправильным.

[EDIT]

Если вы не изменили его и не написали его для string[], как демонстрирует Митч Уит, то вы могли бы просто пропустить шаг преобразования.

[ENDEDIT]

Вот что вам нужно, если вы не используете метод расширения (если у вас уже нет набора потенциальных идентификаторов в виде целых чисел - тогда просто используйте List<int>()). При этом используется синтаксис цепочечного метода, который я считаю более чистым, и выполняет преобразование в int, чтобы обеспечить возможность использования запроса с большим количеством поставщиков.

var uids = arrayofuids.Select(id => int.Parse(id)).ToList();

var selected = table.Where(t => uids.Contains(t.uid));
31 голосов
/ 12 октября 2008

Если вы действительно ищете для репликации Содержит , но для массива, вот метод расширения и пример кода для использования:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ContainsAnyThingy
{
    class Program
    {
        static void Main(string[] args)
        {
            string testValue = "123345789";

            //will print true
            Console.WriteLine(testValue.ContainsAny("123", "987", "554")); 

            //but so will this also print true
            Console.WriteLine(testValue.ContainsAny("1", "987", "554"));
            Console.ReadKey();

        }
    }

    public static class StringExtensions
    {
        public static bool ContainsAny(this string str, params string[] values)
        {
            if (!string.IsNullOrEmpty(str) || values.Length > 0)
            {
                foreach (string value in values)
                {
                    if(str.Contains(value))
                        return true;
                }
            }

            return false;
        }
    }
}
17 голосов
/ 12 октября 2008

Попробуйте следующее.

string input = "someString";
string[] toSearchFor = GetSearchStrings();
var containsAll = toSearchFor.All(x => input.Contains(x));
15 голосов
/ 15 марта 2012

LINQ в .NET 4.0 предлагает вам другую возможность; метод .Any ();

string[] values = new[] { "1", "2", "3" };
string data = "some string 1";
bool containsAny = values.Any(data.Contains);
6 голосов
/ 28 апреля 2011

Или, если у вас уже есть данные в списке и вы предпочитаете другой формат Linq:)

List<string> uids = new List<string>(){"1", "45", "20", "10"};
List<user> table = GetDataFromSomewhere();

List<user> newTable = table.Where(xx => uids.Contains(xx.uid)).ToList();
3 голосов
/ 12 октября 2008

Как насчет:

from xx in table
where stringarray.Contains(xx.uid.ToString())
select xx
2 голосов
/ 13 февраля 2014

Это поздний ответ, но я считаю, что он все еще полезен .
Я создал пакет Nuget для NinjaNye.SearchExtension , который может помочь решить эту проблему.

string[] terms = new[]{"search", "term", "collection"};
var result = context.Table.Search(terms, x => x.Name);

Вы также можете искать несколько строковых свойств

var result = context.Table.Search(terms, x => x.Name, p.Description);

Или выполните RankedSearch, который возвращает IQueryable<IRanked<T>>, который просто включает в себя свойство, которое показывает, сколько раз появлялись условия поиска:

//Perform search and rank results by the most hits
var result = context.Table.RankedSearch(terms, x => x.Name, x.Description)
                     .OrderByDescending(r = r.Hits);

На странице GitHub есть более обширное руководство: https://github.com/ninjanye/SearchExtensions

Надеюсь, что это поможет будущим посетителям

2 голосов
/ 12 октября 2008

Это пример одного способа написания метода расширения (примечание: я бы не использовал это для очень больших массивов; другая структура данных была бы более подходящей ...):

namespace StringExtensionMethods
{
    public static class StringExtension
    {
        public static bool Contains(this string[] stringarray, string pat)
        {
            bool result = false;

            foreach (string s in stringarray)
            {
                if (s == pat)
                {
                    result = true;
                    break;
                }
            }

            return result;
        }
    }
}
1 голос
/ 12 октября 2008

Полагаю, вы могли бы сделать что-то подобное.

from xx in table
where (from yy in string[] 
       select yy).Contains(xx.uid.ToString())
select xx
1 голос
/ 17 апреля 2014

метод расширения Linq. Будет работать с любым объектом IEnumerable:

    public static bool ContainsAny<T>(this IEnumerable<T> Collection, IEnumerable<T> Values)
    {
        return Collection.Any(x=> Values.Contains(x));
    }

Использование:

string[] Array1 = {"1", "2"};
string[] Array2 = {"2", "4"};

bool Array2ItemsInArray1 = List1.ContainsAny(List2);
...