Jak używać LINQ Contains (string[]) zamiast Contains (string)

Mam jedno wielkie pytanie.

Mam zapytanie linq żeby to ująć po prostu wygląda tak:

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

Wartości tablicy string[] będą liczbami takimi jak (1,45,20,10, itd...)

Domyślną wartością dla .Contains jest .Contains(string).

Potrzebuję tego zamiast tego: .Contains(string[])...

EDIT: jeden użytkownik zasugerował napisanie klasy rozszerzenia dla string[]. Chciałbym się dowiedzieć jak, ale czy ktoś wskaże mi właściwy kierunek?

EDIT: the uid would bądź też liczbą. Dlatego jest konwertowany na ciąg znaków.

Pomóc komuś?
Author: Otiel, 2008-10-12

20 answers

Spoulson ma prawie rację, ale najpierw musisz utworzyć List<string> z string[]. Właściwie List<int> byłoby lepiej, gdyby uid był również int. List<T> podpory Contains(). Wykonanie uid.ToString().Contains(string[]) oznaczałoby, że uid jako łańcuch zawiera wszystkie wartości tablicy jako podłańcuch??? Nawet jeśli napiszesz metodę rozszerzenia, jej sens byłby błędny.

[EDIT]

Chyba, że zmieniłeś go i napisałeś dla string[] Jak pokazuje Mitch Wheat, wtedy będziesz możliwość pominięcia kroku konwersji.

[ENDEDIT]

Oto, czego chcesz, jeśli nie wykonasz metody rozszerzenia ( chyba że masz już kolekcję potencjalnych UID jako ints -- użyj zamiast tego List<int>()). Używa składni metody łańcuchowej, która moim zdaniem jest czystsza i czy konwersja do int, aby zapewnić, że zapytanie może być używane z większą liczbą dostawców.

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

var selected = table.Where(t => uids.Contains(t.uid));
 70
Author: tvanfosson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-04 05:35:04

Jeśli naprawdę chcesz replikować zawiera , ale dla tablicy, oto metoda rozszerzenia i przykładowy kod do użycia:

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;
        }
    }
}
 31
Author: Jason Jackson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-18 23:58:02

Spróbuj wykonać następujące czynności.

string input = "someString";
string[] toSearchFor = GetSearchStrings();
var containsAll = toSearchFor.All(x => input.Contains(x));
 17
Author: JaredPar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-31 18:00:10

LINQ w. NET 4.0 ma dla Ciebie inną opcję; the. Metoda Any ();

string[] values = new[] { "1", "2", "3" };
string data = "some string 1";
bool containsAny = values.Any(data.Contains);
 15
Author: RJ Lohan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-14 22:40:46

Lub jeśli masz już dane na liście i wolisz inny format 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();
 5
Author: JumpingJezza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-28 03:31:53

A może:

from xx in table
where stringarray.Contains(xx.uid.ToString())
select xx
 3
Author: spoulson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-12 01:24:42

Jest to przykład jednego sposobu napisania metody rozszerzenia (uwaga: nie używałbym tego do bardzo dużych tablic; inna struktura danych byłaby bardziej odpowiednia...):

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;
        }
    }
}
 2
Author: Mitch Wheat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-12 01:54:24

jest to późna odpowiedź, ale uważam, że nadal jest przydatna .
Stworzyłem NinjaNye.SearchExtension pakiet nuget, który może pomóc rozwiązać ten problem.:

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

Można również przeszukiwać wiele właściwości ciągu

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

Lub wykonaj RankedSearch, która zwraca IQueryable<IRanked<T>>, która zawiera po prostu właściwość pokazującą ile razy pojawiały się wyszukiwane słowa:

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

Istnieje bardziej rozbudowany przewodnik na stronie projects GitHub: https://github.com/ninjanye/SearchExtensions

Nadzieję, że pomoże to przyszłym odwiedzającym

 2
Author: NinjaNye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-13 09:07:50

Wierzę, że możesz też zrobić coś takiego.

from xx in table
where (from yy in string[] 
       select yy).Contains(xx.uid.ToString())
select xx
 1
Author: ctrlShiftBryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-12 01:59:43

Metoda rozszerzenia Linq. Będzie działać z dowolnym liczbą obiektów:

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

Użycie:

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

bool Array2ItemsInArray1 = List1.ContainsAny(List2);
 1
Author: kravits88,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-17 04:34:02

Czy dobrze zakładam, że uid jest unikalnym identyfikatorem (Guid)? Czy to tylko przykład możliwego scenariusza, czy naprawdę próbujesz znaleźć guid pasujący do tablicy ciągów?

Jeśli to prawda, możesz chcieć naprawdę przemyśleć to całe podejście, to wydaje się to naprawdę złym pomysłem. Prawdopodobnie powinieneś próbować dopasować Guid do Guid

Guid id = new Guid(uid);
var query = from xx in table
            where xx.uid == id
            select xx;

Szczerze nie mogę sobie wyobrazić scenariusza, w którym dopasowanie tablicy łańcuchów za pomocą "contains" do zawartości Guid byłoby dobry pomysł. Po pierwsze, Contains() nie gwarantuje kolejności liczb w Guid, więc możesz potencjalnie dopasować wiele elementów. Nie wspominając już o porównywaniu GUID w ten sposób byłoby znacznie wolniejsze niż robienie tego bezpośrednio.

 0
Author: justin.m.chase,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-12 16:38:52

Powinieneś napisać to odwrotnie, sprawdzając, czy lista ID użytkownika zawiera id w tym wierszu tabeli:

string[] search = new string[] { "2", "3" };
var result = from x in xx where search.Contains(x.uid.ToString()) select x;

LINQ zachowuje się tutaj dość jasno i konwertuje go na dobre polecenie SQL:

sp_executesql N'SELECT [t0].[uid]
FROM [dbo].[xx] AS [t0]
WHERE (CONVERT(NVarChar,[t0].[uid]))
IN (@p0, @p1)',N'@p0 nvarchar(1),
@p1 nvarchar(1)',@p0=N'2',@p1=N'3'

Który zasadniczo osadza zawartość tablicy 'search' w zapytaniu sql i filtruje słowem kluczowym 'IN' w SQL.

 0
Author: Gorkem Pacaci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-19 05:31:20

Udało mi się znaleźć rozwiązanie, ale nie świetne, ponieważ wymaga ono użycia AsEnumerable (), która zwróci wszystkie wyniki Z DB, na szczęście mam tylko 1K rekordów w tabeli, więc nie jest to naprawdę zauważalne, ale oto idzie.

var users = from u in (from u in ctx.Users
                       where u.Mod_Status != "D"
                       select u).AsEnumerable()
            where ar.All(n => u.FullName.IndexOf(n,
                        StringComparison.InvariantCultureIgnoreCase) >= 0)
            select u;

mój oryginalny post:

Jak zrobić odwrotnie? Chcę zrób coś takiego w struktura podmiotu.
string[] search = new string[] { "John", "Doe" };
var users = from u in ctx.Users
            from s in search
           where u.FullName.Contains(s)
          select u;

Chcę znaleźć wszystkich użytkowników, gdzie ich pełna nazwa zawiera wszystkie elements in 'search'. Próbowałem wiele różnych sposobów, z których wszystkie nie pracował dla mnie.

I ' ve also tried

var users = from u in ctx.Users select u;
foreach (string s in search) {
    users = users.Where(u => u.FullName.Contains(s));
}

Ta wersja znajduje tylko te, które zawiera ostatni element w wyszukiwaniu / align = "left" /

 0
Author: Brett Ryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-17 10:03:00

Najlepszym rozwiązaniem, jakie znalazłem, było stworzenie funkcji o wartości tabeli w SQL, która generuje wyniki, takie jak::

CREATE function [dbo].[getMatches](@textStr nvarchar(50)) returns @MatchTbl table(
Fullname nvarchar(50) null,
ID nvarchar(50) null
)
as begin
declare @SearchStr nvarchar(50);
set @SearchStr = '%' + @textStr + '%';
insert into @MatchTbl 
select (LName + ', ' + FName + ' ' + MName) AS FullName, ID = ID from employees where LName like @SearchStr;
return;
end

GO

select * from dbo.getMatches('j')

Następnie po prostu przeciągasz funkcję do swojego LINQ.dbml designer i nazywaj go tak, jak robisz inne obiekty. LINQ zna nawet kolumny przechowywanej funkcji. Wołam TAK::

Dim db As New NobleLINQ
Dim LNameSearch As String = txt_searchLName.Text
Dim hlink As HyperLink

For Each ee In db.getMatches(LNameSearch)
   hlink = New HyperLink With {.Text = ee.Fullname & "<br />", .NavigateUrl = "?ID=" & ee.ID}
   pnl_results.Controls.Add(hlink)
Next

Niezwykle prosty i naprawdę wykorzystuje moc SQL i LINQ w aplikacji...i możesz, oczywiście, wygenerować dowolną tabelę o wartości funkcja, którą chcesz uzyskać dla tych samych efektów!

 0
Author: beauXjames,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-18 18:52:59

Wierzę, że to, co naprawdę chcesz zrobić, to: wyobraźmy sobie scenariusz masz dwie bazy danych i mają wspólną tabelę produktów I chcesz wybrać produkty z tabeli "A", które id ma wspólnego z " B "

Użycie metody contains byłoby zbyt skomplikowane, aby to zrobić to, co robimy, to przecięcie i istnieje metoda zwana przecięciem

Przykład z msdn: http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#intersect1

Int [] liczby = (0, 2, 4, 5, 6, 8, 9); int [] numbersB = (1, 3, 5, 7, 8); var = commonNumbers numbersA.Intersect (numbersB);

Myślę, że to, czego potrzebujesz, jest łatwo rozwiązane za pomocą przecięcia

 0
Author: Lucas Cria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-04 03:22:02

Sprawdź tę metodę rozszerzenia:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ContainsAnyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            const string iphoneAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like...";

            var majorAgents = new[] { "iPhone", "Android", "iPad" };
            var minorAgents = new[] { "Blackberry", "Windows Phone" };

            // true
            Console.WriteLine(iphoneAgent.ContainsAny(majorAgents));

            // false
            Console.WriteLine(iphoneAgent.ContainsAny(minorAgents));
            Console.ReadKey();
        }
    }

    public static class StringExtensions
    {
        /// <summary>
        /// Replicates Contains but for an array
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static bool ContainsAny(this string str, params string[] values)
        {
            if (!string.IsNullOrEmpty(str) && values.Length > 0)
                return values.Any(str.Contains);

            return false;
        }
    }
}
 0
Author: ron.camaron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-10 13:55:19
from xx in table
where xx.uid.Split(',').Contains(string value )
select xx
 0
Author: user1119399,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-11 01:34:45

Try:

var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;
 0
Author: Hedego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 16:00:05
string[] stringArray = {1,45,20,10};
from xx in table 
where stringArray.Contains(xx.uid.ToString()) 
select xx
 -1
Author: knroc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-13 14:32:46
Dim stringArray() = {"Pink Floyd", "AC/DC"}
Dim inSQL = From alb In albums Where stringArray.Contains(alb.Field(Of String)("Artiste").ToString())
Select New With
  {
     .Album = alb.Field(Of String)("Album"),
     .Annee = StrReverse(alb.Field(Of Integer)("Annee").ToString()) 
  }
 -2
Author: EVONZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-16 18:54:17