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

głosy
81

Mam jedno wielkie pytanie.

Mam kwerendy LINQ, aby umieścić go po prostu wygląda tak:

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

Wartości string[]tablicy byłoby numery takie jak (1,45,20,10, etc ...)

Domyślne za .Containsto .Contains(string).

Muszę to zrobić to zamiast: .Contains(string[])...

EDIT: Jeden z użytkowników zaproponował napisanie klasy rozszerzenie dla string[]. Chciałbym nauczyć, ale ktoś chętny do pkt mnie we właściwym kierunku?

EDIT: UID byłby również liczbą. Dlatego to jest konwertowany do łańcucha.

Pomoże ktoś?

Utwórz 12/10/2008 o 02:14
źródło użytkownik
W innych językach...                            


21 odpowiedzi

głosy
69

spoulson ma ona prawie rację, ale trzeba stworzyć List<string>od string[]początku. Rzeczywiście List<int>byłoby lepiej, gdyby uid jest również int. List<T>wspiera Contains(). Robi uid.ToString().Contains(string[])oznaczałoby, że uid jako ciąg zawiera wszystkie wartości tablicy jako podciąg ??? Nawet jeśli nie napisać metodę rozszerzenia poczucie byłoby źle.

[EDYTOWAĆ]

Chyba że zmienił go wokół i napisał go string[]jako Mitch Wheat demonstruje, że wtedy po prostu być w stanie pominąć etap konwersji.

[ENDEDIT]

Oto, co chcesz, jeśli nie zrobić metodę rozszerzenia (o ile nie masz już zbiór potencjalnych UID jak wskazówki - następnie wystarczy użyć List<int>()zamiast). Ta metoda wykorzystuje przykuty składni, co moim zdaniem jest czystsze i robi konwersję do int w celu zapewnienia, że zapytanie może być używany z kilku dostawców.

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

var selected = table.Where(t => uids.Contains(t.uid));
Odpowiedział 12/10/2008 o 03:01
źródło użytkownik

głosy
31

Jeśli jesteś naprawdę szuka replikować Zawiera , ale na tablicy, tutaj jest metoda rozszerzenie i przykładowy kod do wykorzystania:

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;
        }
    }
}
Odpowiedział 12/10/2008 o 17:00
źródło użytkownik

głosy
17

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

string input = "someString";
string[] toSearchFor = GetSearchStrings();
var containsAll = toSearchFor.All(x => input.Contains(x));
Odpowiedział 12/10/2008 o 03:03
źródło użytkownik

głosy
14

LINQ w .NET 4.0 ma innej opcji dla ciebie; przycisk (metoda) .Any;

string[] values = new[] { "1", "2", "3" };
string data = "some string 1";
bool containsAny = values.Any(data.Contains);
Odpowiedział 14/03/2012 o 23:40
źródło użytkownik

głosy
5

Lub jeśli masz już dane na liście i preferuje 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();
Odpowiedział 28/04/2011 o 04:31
źródło użytkownik

głosy
3

Co powiesz na:

from xx in table
where stringarray.Contains(xx.uid.ToString())
select xx
Odpowiedział 12/10/2008 o 02:24
źródło użytkownik

głosy
2

Jest to późna odpowiedź, ale uważam, że jest nadal przydatny .
I stworzyli NinjaNye.SearchExtension Nuget pakiet, który może pomóc rozwiązać ten problem bardzo .:

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

Można również wyszukiwać wiele właściwości ciągów

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

Lub wykonać RankedSearchktóra zwraca IQueryable<IRanked<T>>który po prostu zawiera właściwość, która pokazuje, ile razy pojawił terminy wyszukiwania:

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

Jest bardziej obszerny poradnik projektów GitHub stronie: https://github.com/ninjanye/SearchExtensions

Nadzieję, że to pomoże przyszłych gości

Odpowiedział 13/02/2014 o 10:07
źródło użytkownik

głosy
2

Jest to przykład jednego sposobu pisania metodę rozszerzenia (uwaga: nie będę korzystać z tego za bardzo dużych tablic; kolejna struktura danych byłoby bardziej odpowiednie ...):

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;
        }
    }
}
Odpowiedział 12/10/2008 o 02:54
źródło użytkownik

głosy
1

Metoda rozszerzenie LINQ. Będzie współpracować z dowolnym IEnumerable obiektu:

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

Stosowanie:

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

bool Array2ItemsInArray1 = List1.ContainsAny(List2);
Odpowiedział 17/04/2014 o 04:55
źródło użytkownik

głosy
1

Wierzę, można również zrobić coś takiego.

from xx in table
where (from yy in string[] 
       select yy).Contains(xx.uid.ToString())
select xx
Odpowiedział 12/10/2008 o 02:59
źródło użytkownik

głosy
0
var SelecetdSteps = Context.FFTrakingSubCriticalSteps
             .Where(x => x.MeetingId == meetid)
             .Select(x =>    
         x.StepID  
             );

        var crtiticalsteps = Context.MT_CriticalSteps.Where(x =>x.cropid==FFT.Cropid).Select(x=>new
        {
            StepID= x.crsid,
            x.Name,
            Checked=false

        });


        var quer = from ax in crtiticalsteps
                   where (!SelecetdSteps.Contains(ax.StepID))
                   select ax;
Odpowiedział 06/03/2019 o 11:05
źródło użytkownik

głosy
0

Próbować:

var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;
Odpowiedział 08/08/2015 o 13:17
źródło użytkownik

głosy
0

Zaznacz 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;
        }
    }
}
Odpowiedział 10/08/2012 o 14:55
źródło użytkownik

głosy
0
from xx in table
where xx.uid.Split(',').Contains(string value )
select xx
Odpowiedział 30/07/2012 o 08:02
źródło użytkownik

głosy
0

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

stosując metodę zawiera byłoby zbyt skomplikowane, by robić to, co robimy, jest skrzyżowanie, a tam jest metoda zwana skrzyżowanie na które

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

Int [] Numery = (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ązać przy skrzyżowaniu

Odpowiedział 04/08/2010 o 04:22
źródło użytkownik

głosy
0

Najlepszym rozwiązaniem znalazłem iść do przodu i utworzyć funkcję wycenione tabela w SQL, która produkuje 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ągnij funkcję do projektanta LINQ.dbml i nazywają to jak to zrobić swoje inne obiekty. LINQ nawet wie kolumny swojej funkcji składowanej. Ja nazywam go 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ę utlizes moc SQL i LINQ w aplikacji ... i można, oczywiście, generują żadnej tabeli wycenione funkcji chcesz za te same efekty!

Odpowiedział 18/06/2010 o 19:52
źródło użytkownik

głosy
0

Udało mi się znaleźć rozwiązanie, ale nie świetny, ponieważ wymaga użycia AsEnumerable (), która ma zamiar powrócić wszystkie wyniki z DB, na szczęście mam tylko 1k rekordy w tabeli, tak naprawdę to nie jest wyczuwalny, ale tu 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 następująco:

Jak to zrobić na odwrót? Chcę zrobić coś jak następuje w ramach jednostki.

string[] search = new string[] { "John", "Doe" };
var users = from u in ctx.Users
            from s in search
           where u.FullName.Contains(s)
          select u;

Co chcę jest znalezienie wszystkich użytkowników, gdzie ich FullName zawiera wszystkie elementy w `search”. Próbowałem kilka różnych sposobów, z których nie wszystkie zostały pracujących dla mnie.

Próbowałem zostały również

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

Ta wersja znajdzie tylko te, które zawierają ostatni element w tablicy wyszukiwania.

Odpowiedział 17/07/2009 o 10:21
źródło użytkownik

głosy
0

należy napisać to w drugą stronę, sprawdzając swoją priviliged lista id użytkownika zawiera identyfikator na 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ę dość jasny tutaj i konwertuje go do dobrego 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óra w zasadzie osadza zawartość „Szukaj” tablicy w zapytaniu SQL i nie filtrowanie z „in” słów kluczowych w SQL.

Odpowiedział 19/01/2009 o 06:17
źródło użytkownik

głosy
0

Więc ja poprawnie zakładając, że UID to unikalny identyfikator (GUID)? Jest to tylko przykład możliwego scenariusza czy ty naprawdę próbuje znaleźć GUID, który pasuje tablicę ciągów?

Jeśli jest to prawda, może chcesz naprawdę przemyśleć całe to podejście wydaje się to naprawdę zły pomysł. Należy prawdopodobnie próbując dopasować Guid do GUID

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

Szczerze nie mogę wyobrazić sobie scenariusz, w którym dopasowanie tablicę ciągów za pomocą „zawiera” z treścią GUID byłoby dobrym pomysłem. Z jednej strony, contains () nie będzie gwarantować kolejność liczb w GUID więc potencjalnie można dopasować kilka pozycji. Nie wspominając już o porównywaniu GUID tędy droga będzie wolniejsze niż po prostu robi to bezpośrednio.

Odpowiedział 12/10/2008 o 17:38
źródło użytkownik

głosy
-1
string[] stringArray = {1,45,20,10};
from xx in table 
where stringArray.Contains(xx.uid.ToString()) 
select xx
Odpowiedział 31/08/2010 o 18:48
źródło użytkownik

głosy
-2
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()) 
  }
Odpowiedział 16/10/2016 o 18:21
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more