2017-01-06 18 views
-3

私はC#とLinqの新機能です重複するレコードを削除するには1つの問題がありますDeptを持たない人物を重複して削除してください。以下は、従業員のリストにこの 出力例のようにlinqを使用してフィールドのリストから重複を削除

private static void Main() 
    { 
     List<Employee> empList = new List<Employee>(); 

     empList.Add(new Employee() { ID = 1, Name = "John", Age=23, Dept='computer'}); 
     empList.Add(new Employee() { ID = 2, Name = "Mary", Age=25, Dept='computer'}); 
     empList.Add(new Employee() { ID = 3, Name = "Amber",Age=23, Dept=''}); 
     empList.Add(new Employee() { ID = 4, Name = "Kathy",Age=25, Dept=''}); 
     empList.Add(new Employee() { ID = 5, Name = "Lena", Age=27, Dept='computer'}); 
     empList.Add(new Employee() { ID = 6, Name = "John", Age=28, Dept=''}); 
     empList.Add(new Employee() { ID = 7, Name = "Kathy",Age=27, Dept='Tester'}); 
empList.Add(new Employee() { ID = 8, Name = "John", Age=23, Dept='computer'}); 
     var dup = empList 
      .GroupBy(x => new { x.FName }) 
      .Select(group => new { Name = group.Key, Count = group.Count() }) 
      .OrderByDescending(x => x.Count); 

     foreach (var x in dup) 
     { 
      Response.Write(x.Count + " " + x.Name); 
     } 
    } 
    class Employee 
    { 
     public int ID { get; set; } 
     public string FName { get; set; } 
     public int Age { get; set; } 
     public char Dept { get; set; } 
    } 

最終出力の外観を使用した簡単な例である: -

empList.Add(new Employee() { ID = 1, Name = "John", Age=23, Dept='computer'}); 
     empList.Add(new Employee() { ID = 2, Name = "Mary", Age=25, Dept='computer'}); 
     empList.Add(new Employee() { ID = 3, Name = "Amber",Age=23, Dept=''}); 
     empList.Add(new Employee() { ID = 5, Name = "Lena", Age=27, Dept='computer'}); 
     empList.Add(new Employee() { ID = 7, Name = "Kathy",Age=27, Dept='Tester'}); 
empList.Add(new Employee() { ID = 8, Name = "John", Age=23, Dept='computer'}); 

私はそれらの重複したレコードを削除する必要がDEPTを持っていけない人たち。

条件1 重複レコードは複数回出ますが、削除する必要のあるdeptを持たない1つのレコードです。そして残りのレコードが(Deptが文字列のようです)IDが一意であるので、あなたがこのアプローチを使用することができ、出力

+0

重複との両方があるのであれば 'Dept'は、あなたは両方を維持するだろうか? – juharr

+0

同じ名前の重複を検討していますか? – krillgar

+0

そして、部署のない非重複従業員はどうですか? –

答えて

1

に表示されます:

var empDupNoDepartment = empList 
    .GroupBy(x => String.IsNullOrEmpty(x.Dept) ? int.MinValue : x.ID) 
    .Select(group => group.First()) 
    .ToList(); 

これは、空のDeptを持つ唯一の最初の従業員を保持します。

+0

私は、Deptを持っている同じ名前のレコードがあれば、OPは空の 'Dept'レコードを削除したいと思うと思います。 – juharr

+0

@juharr:しかし、予想される出力は何か異なることを示唆しています。アンバーは維持されていますが、他の従業員はいません。空の 'Dept'の最初のものです。私の理解は:すべての空のDept複製を削除し、最初のものだけを残す。他の従業員はすべて残っています –

+0

同じ名前のレコードと「Dept」があるのでレコード4と6が削除されたことを意味していましたが、その名前のレコードがないためレコード3が保持されます。あなたのアプローチがサンプルの入力/出力に対して同じ結果を与えることになりますが、OPが言っているものと一致するようには見えません。 – juharr

-2

私はそれについてはよく分からないんだけど、あなただけのLINQと空の部門の従業員を削除したい場合は、行うことができる必要があります:

empList = empList.Where(Dept => !string.IsNullOrWhiteSpace(Dept)).Distinct().ToList() 

よろしく!

+0

タイプがIEquatable – ironstone13

+0

を実装していない場合、Distinctは参照の等価を使用します。わからない場合は、元のポスターの説明を求めてから、その答えを推測してください。 –

+0

私は同じことをしていますが、別称を使用する必要はありません – buggy3

-1

ここには、誰かの名前が何のためにもひどいプライマリキーである理由の例があります。

すべての値:

var hasDept = empList.Where(x=>x.Dept != null && x.Dept.Trim() != string.Empty).ToList(); 

個別値:

var hasDept = empList.Where(x=>x.Dept != null && x.Dept.Trim() != string.Empty).Distinct().ToList(); 

それらはあなたの部門を持っているものを取得します。あなたも1を持っていないが、部門を持っている重複したエントリを持っていないものを取得したい場合は、最も簡単な方法は、おそらく次のとおりです。名前で

var noDept = empList.Where(x=>x.Dept == null || x.Dept.Trim() == string.Empty).Distinct().ToList() //gets all the ones with no dept 

var all = noDept; 
foreach(var e in all) 
{ 
     if(hasDept.Where(x.Name == e.Name).Count == 0) 
      all.Add(e); 
} 
+0

'Equals'と' GetHashCode'をオーバーライドしないクラスのコレクションで 'Distinct'を使用すると、何かを取り除く。 – juharr

0
from e in empList 
group e by e.Name into g 
select g.FirstOrDefault(e => !String.IsNullOrEmpty(e.Dept)) ?? g.First(); 

ジャスト・グループとDeptで最初の従業員を選択するか、最初の従業員のみを選択します。

出力:

[ 
    { "ID": 1, "Name": "John", "Age": 23, "Dept": "computer" }, 
    { "ID": 2, "Name": "Mary", "Age": 25, "Dept": "computer" }, 
    { "ID": 3, "Name": "Amber", "Age": 23,"Dept": "" }, 
    { "ID": 7, "Name": "Kathy", "Age": 27, "Dept": "Tester" }, 
    { "ID": 5, "Name": "Lena", "Age": 27, "Dept": "computer" } 
] 

あなたが空でない部門ですべてのエントリを保持したい場合は、

Func<Employee, bool> hasDept = e => !String.IsNullOrEmpty(e.Dept); 
var result = empList 
     .GroupBy(e => e.Name) 
     .SelectMany(g => g.Any(hasDept) ? g.Where(hasDept) : g.Take(1)); 

クエリ構文:

from e in empList 
group e by e.Name into g 
from e in g.Any(hasDept) ? g.Where(hasDept) : g.Take(1) 
select e; 

出力:

[ 
    { "ID": 1, "Name": "John", "Age": 23, "Dept": "computer" }, 
    { "ID": 8, "Name": "John", "Age": 23, "Dept": "computer" }, <== difference 
    { "ID": 2, "Name": "Mary", "Age": 25, "Dept": "computer" }, 
    { "ID": 3, "Name": "Amber", "Age": 23,"Dept": "" }, 
    { "ID": 7, "Name": "Kathy", "Age": 27, "Dept": "Tester" }, 
    { "ID": 5, "Name": "Lena", "Age": 27, "Dept": "computer" } 
] 
+0

私はまだOPが何を望んでいるのか正確には分かっていませんが、最新のアップデートではJohnという名前のレコードが3つあり、空の 'Dept'を持つレコードだけが削除されます。 – juharr

+0

@juharrうん、私はまだOPが望むものを手に入れません。いくつかの名前を持つすべてのレコードにDeptがない –

0

このクラスを作成します。

class Dept 
{ 
    public int Count { get; set; } 
    public string Name { get; set; } 
    public List<Employee> Employees { get; set; } 
} 

そして、ここでは、クエリです:

var dup = empList 
    .GroupBy(x => new { x.Name }) 

    // Employees with duplicate name 
    .Select(group => new { Emps = group.Select(x => x)}) 

    // From duplicates select only those that have a department 
    .SelectMany(x => { 
     var emps = x.Emps.Where(y => !string.IsNullOrWhiteSpace(y.Dept)); 
     var employeesWithDept = emps.GroupBy(g => g.Name); 


     IEnumerable<Dept> a = 
     employeesWithDept.Select(g => new Dept { Employees = g.ToList(), Name = g.Key.ToString(), Count = g.Count()}); 
     return a; 
    }) 
    .OrderByDescending(x => x.Count); 
関連する問題