2016-09-15 9 views
2
public class Contact 
    { 
     public string Name { get; set; } 
     public string Fax { get; set; } 
     public string Email {get; set; } 
    } 

を組み合わせますかC#のコレクションは、エントリ

╔═════╦══════╦═════════════╗ 
║Name ║ Fax ║ Email  ║ 
╠═════╬══════╬═════════════╣ 
║ a ║ 1 ║ [email protected] ║ 
║ b ║ 2 ║ [email protected] ║ 
║ c ║ 3 ║ [email protected] ║ 
╚═════╩══════╩═════════════╝ 

これは私がこれまで試したものです:

var result = contactList.Select(contact => contact.Name) 
          .Distinct() 
          .Select(name => contactList.First(contact => contact.Name == name)) 
          .ToList(); 


foreach (var contact in contactList) 
      { 
       var c = result.First(r => r.Name == contact.Name); 
       c.Name = string.IsNullOrWhiteSpace(contact.Name) ? c.Name : contact.Name; 
       c.Fax = string.IsNullOrWhiteSpace(contact.Fax ? c.Fax : contact.Fax; 
       c.Email = string.IsNullOrWhiteSpace(contact.Email) ? c.Email : contact.Email; 
      } 

は、より効率的な方法はありますか?

+3

あなたの重複した定義は何ですか?あなたの望む結果は何ですか? –

+0

あなたは類似アイテムをどのように組み合わせるかを尋ねていますか?私の定義では重複がないので、何が "重複"を構成しますか? – leigero

+0

'List 'をビルドするときに余分な情報を追加するほうが効率的かもしれません。 –

答えて

4

GroupByを実行する必要があり、それらの値がNULL値であると仮定しているので、最初のNULL以外の値を取得したいだけです。

var results = (from contact in constactList 
       group contact by contact.Name into contacts 
       select new Contact 
       { 
        Name = contacts.Key, 
        Fax = contacts.FirstOrDefault(c => c.Fax != null)?.Fax, 
        Email = contacts.FirstOrDefault(c => c.Email != null)?.Email 
       }).ToList(); 

またはメソッドの構文で

var results = constactList.GroupBy(contact => contact.Name) 
    .Select(contacts => new Contact 
    { 
     Name = contacts.Key, 
     Fax = contacts.FirstOrDefault(c => c.Fax != null)?.Fax, 
     Email = contacts.FirstOrDefault(c => c.Email != null)?.Email 
    }).ToList(); 

それとも彼らは空白の文字列をしている場合も

Fax = contacts.FirstOrDefault(c => !string.IsNullOrWhiteSpace(c.Fax))?.Fax 

を行うことができそして、あなたはそれからC#6を持っていない場合

を次
Fax = contacts.Where(c => !string.IsNullOrWhiteSpace(c.Fax)).Select(c => c.Fax).FirstOrDefault() 
+0

ありがとうございます。あなたのソリューションは非常に明確で徹底的です。 – user941749

1

辞書を使用することができます。リストを繰り返して欠落した情報を取得し、重複を除外します。

var dict = new Dictionary<string, Contact>(); 
foreach (var contact in contactList) 
{ 
    Contact existingContact; 
    if (dict.TryGetValue(contact.Name, out existingContact)) 
    { 
     if (String.IsNullOrEmpty(existingContact.Fax)) 
      existingContact.Fax = contact.Fax; 
     if (String.IsNullOrEmpty(existingContact.Email)) 
      existingContact.Email = contact.Email; 
    } 
    else 
    { 
     dict.Add(contact.Name, contact); 
    } 
} 
var list = dict.Values.ToList(); 

このメソッドの複雑さはO(n)です。また、O(n)の追加メモリが必要です。

0

あなたは、電子メールまたはファックスのないエントリが存在する可能性があります。

var contactList = new List<Contact> { 
    new Contact { Name="a", Fax = "1", Email=""}, 
    new Contact { Name="b", Fax = "", Email="[email protected]"}, 
    new Contact { Name="c", Fax = "3", Email="[email protected]"}, 
    new Contact { Name="a", Fax = "", Email="[email protected]"}, 
    new Contact { Name="b", Fax = "2", Email=""}, 

}; 

var result = (from c in contactList 
       .Where(contact => !string.IsNullOrEmpty(contact.Name)) 
       .Select(c => c.Name) 
       .Distinct() 
      let fax = contactList.FirstOrDefault(contact => contact.Name == c && 
        !string.IsNullOrEmpty(contact.Fax)) 
      let email = contactList.FirstOrDefault(contact => contact.Name == c && 
        !string.IsNullOrEmpty(contact.Email)) 
      select new Contact { 
       Name = c, 
       Fax = fax == null ? "" : fax.Fax, 
       Email = email == null ? "" : email.Email 
      }) 
      .ToList(); 
関連する問題