IT

Contains (string) 대신 LINQ Contains (string [])를 사용하는 방법

lottoking 2020. 9. 1. 07:41
반응형

Contains (string) 대신 LINQ Contains (string [])를 사용하는 방법


큰 질문이 하나 있습니다.

간단히 다음과 같이 표시하는 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도 숫자가 될 것입니다. 이것이 링크로 변환되는 이유입니다.

누구 도와?


spoulson 거의 바로 그것을 가지고 있지만,은 만들어야 당신 List<string>에서 string[]첫번째. 실제로 List<int>uid가이면 a 가 더 int좋습니다. List<T>지원합니다 Contains(). 이렇게 uid.ToString().Contains(string[])많은로 UID가 많은로 배열의 값이 모두 포함되어 있음 암시 ??? 확장 방법을 작성해도 그 의미는 틀릴 것입니다.

[편집하다]

string[]Mitch Wheat가 설명 하는 대로 변경하여 작성하지 않는 한 변환 단계를 건너 뛸 수 있습니다.

[종료]

확장 방법을 사용하지 않는 경우 원하는 경우 다음과 같음 (이미 int로 외장 uid 컬렉션이있는 경우 List<int>()대신 사용하는 경우). 이것은 내가 더 깔끔하고 생각하는 체인 메서드 구문을 사용하고 쿼리를 더 많은 공급자와 함께 사용할 수있는 int로 변환합니다.

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

var selected = table.Where(t => uids.Contains(t.uid));

포함을 복제 하고 싶지만 배열의 경우 사용할 확장 메서드 와 샘플 코드는 다음과 가변적입니다.

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;
        }
    }
}

다음을 시도하십시오.

string input = "someString";
string[] toSearchFor = GetSearchStrings();
var containsAll = toSearchFor.All(x => input.Contains(x));

.NET 4.0의 LINQ에는 또 다른 옵션이 있습니다. .Any () 메서드;

string[] values = new[] { "1", "2", "3" };
string data = "some string 1";
bool containsAny = values.Any(data.Contains);

또는 이미 목록에 데이터가 있고 다른 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();

어때 :

from xx in table
where stringarray.Contains(xx.uid.ToString())
select xx

(참고 : 매우 큰 배열에 사용하지 않을 것입니다. 다른 데이터 구조가 더 분명 할 것입니다 ...).

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;
        }
    }
}

이것은 늦은 대답이지만 여전히 유용하다고 생각합니다 . 이 문제를 해결하는 데 도움이
되는 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

이것이 미래 방문자에게 도움이되기를 바랍니다.


나는 당신도 이와 같은 것을 할 수있는 믿습니다.

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

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);

uid가 고유 식별자 (Guid)라고 가정하고 있습니까? 이것이 가능한 시나리오의 예일 뿐입니 까 아니면 배열과 일치하는 GUID를 어디에 있습니까?

이것이 사실이라면 모든 접근 방식을 다시 생각하고 싶을 수 있습니다. 이것은 정말 나쁜 생각처럼. Guid와 Guid를 일치 시키려고 할 것입니다.

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

솔직히 "contains"를 사용하여 배열을 Guid의 내용과 일치하는 시나리오를 상상할 수 없습니다. 한 가지로, 포함 ()은 Guid의 숫자 순서를 보장하지 않습니다. 여러 항목을 일치시킬 수 있습니다. 방식 방식으로 guid를 비교하는 것은 말할 것도없이 직접 수행하는 것보다 훨씬 느릴 것입니다.


권한이 부여 된 사용자 ID 목록에 해당 테이블 행의 ID가 포함되어 있는지 확인하여 다른 방법으로 작성해야합니다.

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

LINQ는 여기에서 매우 밝게 작동하며이를 좋은 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'

기본적으로 '검색'배열의 내용을 SQL 쿼리에 포함하고 SQL에서 'IN'키워드로 필터링을 수행합니다.


나는 해결책을 찾을 수 있었지만 DB에서 모든 결과를 반환하는 AsEnumerable ()을 사용해야하므로 훌륭한 해결책은 아닙니다. 다행히도 테이블에 1k 레코드 만 있으므로 실제로는 눈에 띄지 않지만 여기에 있습니다. .

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;

내 원래 게시물은 다음과 같습니다.

반대로 어떻게합니까? 엔티티 프레임 워크에서 다음과 같은 작업을하고 싶습니다.

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

내가 원하는 것은 FullName이 '검색'의 모든 요소를 ​​포함하는 모든 사용자를 찾는 것입니다. 나는 여러 가지 방법을 시도했지만 모두 나를 위해 일하지 않았습니다.

나는 또한 시도했다

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

이 버전은 검색 배열의 마지막 요소를 포함하는 항목 만 찾습니다.


내가 찾은 최고의 솔루션은 계속해서 ::와 같은 결과를 생성하는 SQL에서 테이블 반환 함수를 만드는 것입니다.

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')

그런 다음 함수를 LINQ.dbml 디자이너로 끌어서 다른 개체처럼 호출하면됩니다. LINQ는 저장된 함수의 열도 알고 있습니다. 나는 이것을 이렇게 부른다 ::

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

놀랍도록 간단하고 애플리케이션에서 SQL 및 LINQ의 강력한 기능을 실제로 활용합니다. 물론 동일한 효과를 위해 원하는 테이블 값 함수를 생성 할 수 있습니다!


저는 여러분이 정말로하고 싶은 것은 다음과 같습니다 : 두 개의 데이터베이스가 있고 공통 제품 테이블이있는 시나리오를 상상해 봅시다. 그리고 ID가 "B"와 공통 인 테이블 "A"에서 제품을 선택하려고합니다.

contains 메소드를 사용하는 것은 너무 복잡해서 우리가하고있는 것은 교차로라고하는 메소드가 있습니다.

msdn의 예 : http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#intersect1

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

필요한 것은 교차로로 쉽게 해결할 수 있다고 생각합니다


이 확장 방법을 확인하십시오.

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;
        }
    }
}

from xx in table
where xx.uid.Split(',').Contains(string value )
select xx

시험:

var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;

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;

string[] stringArray = {1,45,20,10};
from xx in table 
where stringArray.Contains(xx.uid.ToString()) 
select xx

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()) 
  }

참고 URL : https://stackoverflow.com/questions/194930/how-do-i-use-linq-containsstring-instead-of-containsstring

반응형