2011-01-10 6 views
1

아래의 linq는 내 두뇌에 너무 jedi입니다. 가능한 한 무엇을하려고합니까?Linq 여러 테이블에서 구별됩니까?

var aa = new string[] { "1", "2" }; 
var bb = new string[] { "1", "2", "3" }; 
var cc = new string[] { "2" }; 

//*cannot directly reference the above anymore*// 
var dd = new string[][] { aa, bb, cc }; 
//result = dd.**magical linq to only get item(s) present in each table** i.e. result = {"2"} 
+0

나는 '마법의 linq'을 읽을 때 실제로 웃었다. – Kredns

답변

3
var result = dd.Aggregate<IEnumerable<string>>((a, x) => a.Intersect(x)); 

당신이 더 나은 이론적 인 성능을 약간하려는 경우를 대신 다음을 수행 할 수 있습니다. 각각의 교차 연산에 대해 새로운 세트를 구성 할 필요가 없으며 명시 적 HashSet<T>을 사용하여 결과를 일반 IEnumerable<T>이 아닌 다음 반복으로 전달합니다.

var result = dd.Aggregate((HashSet<string>)null, 
          (a, x) => { 
             if (a == null) 
              a = new HashSet<string>(x); 
             else 
              a.IntersectWith(x); 
             return a; 
            }); 
+0

왜 이것이 예를 들어 가입하는 것보다 효과적입니까? 나를 위해 가입을 사용해야하는 것 같습니다.나의 늦은 대답을 보아라. 그러나 그것은'Aggregate'와 함께 좋은 해결책이다 :). –

+0

-1, Linq 공급자가 효율적으로 작업하게하는 대신 모든 결과 처리를 CLR 개체로 푸시; 이것도 올바른 대답 ({ "2"})을 제공합니까, 나는 의심하지 않습니까? – RichardW1001

+0

@ 리차드 : 이것이 LINQ-to-Objects의 경우 - 질문의 예가 ​​확실합니다. 데이터 소스가'string [] []'배열 인 경우 - LINQ 공급자를 효율적으로 사용하고 있습니다. 그리고 실제로 옳은 대답을 주 었는지 의심스럽지 않고 왜 당신의 의심보다 오히려 사실에 기초하여 당신의 하향 회선을 테스트합니까? – LukeH

3

거기에 niftier 방법이 될 수 있지만, 당신은 루프에서 쿼리 구축 할 수 있습니다 : 다음, 일부 가독성을 희생

var aa = new string[] { "1", "2" }; 
var bb = new string[] { "1", "2", "3" }; 
var cc = new string[] { "2" }; 

var dd=new string[][] { aa, bb, cc }; 

IEnumerable<string> q=dd.First(); 

for(var i=1;i<dd.Length;++i) 
{ 
    q=q.Intersect(dd[i]); 
} 
+0

Linq의 요점은 루프를 피하는 것입니까? – RichardW1001

+0

@ 리차드 : LINQ의 핵심은 루프를 피하는 것이 아닙니다. 코드를 더욱 표현적이고 읽기 쉽도록 만드는 것입니다. 일반 루프가 LINQ에 상응하는 것보다 읽기 쉬운 경우가 종종 있습니다. – LukeH

+0

예, 아니요, 가독성이 중요하다는 데 동의하지만 많은 경우 Linq는 기본 Linq 제공 업체가 작동하는 방식에 따라 다르게 작동하고 루프를 실행하여 해당 기능을 제거합니다. 가장 눈에 띄는 예는 표현식이 SQL로 변환되어 데이터베이스에서 실행되는 SQL 제공자입니다. 루프를 실행하면 성능 비용으로 해당 단계를 건너 뜁니다. – RichardW1001

3

당신은 세트 사업자 사용할 수 있습니다 - 연합 (EU), 교차 등

(편집 - 오독 한 질문!)

내가 교차 당신이 바로 상자 밖으로 계신 당신을 제공 믿는다

var dd = aa.Intersect(bb).Intersect(cc); 

aa bb와 cc는 이미 같은 유형의 모든 IEnumerable이므로 작동합니다. 당신이 ToArray(), ToList에 체인 수 있도록

var dd = aa.Select(a => a.PropertyA).Intersect(bb.Select(b => b.PropertyB).Intersect(cc.Select(c => c.PropertyC); 

결과를을 IQueryable있을 것입니다 : 당신의 IEnumerables가 (다른 Linq를 테이블에서 같은) 다른 유형의 경우에 당신은 당신이 원하는 속성을 투사해야합니다() 등을 사용하여 원하는 결과를 얻습니다.

0

간단한 결합을 사용하지 않는 이유는 무엇입니까? > 당신은 SQL에 LINQ를 사용하고 있고 IEnumerable을 <에 복합 쿼리의 일부를 캐스팅하는 경우

class Program 
{ 
    static void Main(string[] args) 
    { 
     var aa = new string[] { "1", "2", "4" }; 
     var bb = new string[] { "1", "2", "3", "4" }; 
     var cc = new string[] { "2", "4" }; 

     //*cannot directly reference the above anymore*// 
     var dd = new string[][] { aa, bb, cc }; 

     var result = dd.Aggregate((x, y) => x.Join(y, z => z, z => z, (z, v) => z).ToArray()); 
     foreach (var item in result) 
     { 
      Console.WriteLine(item); 
     } 
     Console.ReadLine(); 
    } 
} 
3

주의, 그 부분은 하나의 SQL 쿼리를 형성하는 쿼리의 나머지 부분과 결합 할 수 없습니다. 쿼리가 암시 적으로 IEnumerable <>에 'q'로 할당 될 때 spander에 의한 예제의 데이터 소스로 SQL을 사용하여이 작업이 수행됩니다. 대신 IQueryable을 사용하십시오. 각 IEnumerable은 지연되지만 3 개의 SQL 쿼리가 서버로 전송되고 교차 부분은 메모리 내에서 수행됩니다.

Returning IEnumerable<T> vs. IQueryable<T>을 참조하거나 참조를 얻으려면 "IEnumerable vs IQueryable"을 검색하십시오.

관련 문제