2012-05-03 8 views
0

以下のコードは、コンマで区切られた電子メールで構成された文字列を検索し、string型の結果コレクションにない場合は電子メールを追加します。別の方法String.Splitを使用する

string [] oEmails=orderEmails.Split(','); 
string[] partEmails= part[Constants.Emails].ToString().Split(','); 
foreach(string email in oEmails) 
{ 
    if(!partEmails.Contains(email)) 
    { 
     part[Constants.Emails] += "," + email; 
    } 
} 

これは、このロジックを書き込むための最良の方法ですか?私はうまくいきますが、このロジックをラムダ式に統合する方法があるのだろうかと疑問に思っていましたか?

私はこれらの配列で何もしていませんが、入力文字列を分割しています。彼らは他の目的を果たしていません。

+0

を試すことができますか?あなたが達成しようとしていることは明確ではないので、推薦は来るのが難しいです。 – Oded

+0

入力文字列を分割するだけです。だからこそ私はこのようなことをしない。 –

+0

しかし、あなたはもっともっとやっている。あなたは何のために配列を分割していますか? – Oded

答えて

3
part[Constants.Emails] = 
string.Join(",", part[Constants.Emails].Split(',').Union(orderEmails.Split(',')).ToArray()); 

さらに、電子メールを間違った方法で保存しています。それらをコンマ区切りの文字列として格納しないで、リストとして格納します。そうすれば、 "コレクション"を変更するたびにそれらを解析する必要はありません。

+0

これはすべての中で最もクリーンな解決策だと思います。それは不要なチェックを避けますが、cAsInGに基づいて重複を考慮する必要があります。 'Union'は比較子を指定することができるので、多くの' StringComparer'インスタンスの1つを提供できます。 – SPFiredrake

0
part[Constant.Emails] += oEmails.Where(email => !partEmails.Contains(email)) 
           .Aggregate(b, (current, email) 
               => current + ("," + email)); 

まず、これはそれが少数,mail部(第3行目)の文字列にそれらを集約し、まだ存在していない電子メール(最初の行)を選択します。その後、それを文字列(最初の行)に追加します。

+0

[email protected]がリストにあり、[email protected]を追加しようとするとどうなりますか? "[email protected]"の部分文字列であり、追加する必要がないと判断したので、 "[email protected]"はすでにリストに入っています。 –

+0

@ティムズ:これを目の当たりにするのは2番目です。これは 'List.Contains'であり、' String.Contains'ではないことに注意してください。これは、OPアプローチからの正確な再現であり、実際にReSharperを使用して一方から他方に変換されています。 –

+0

おっと、私の間違い。私は他の人がそれに対するあなたの反応を見ることができるようにコメントを残します。 –

0

この方法では、文字列内で直接検索を実行することによって、あなたのpart[Constants.Emails].Split(',')を回避:

string[] oEmails = orderEmails.Split(','); 
string partEmails = part[Constants.Emails]; 

foreach (string email in oEmails) 
{ 
    bool index = partEmails.IndexOf(email); 
    bool isAlreadyPresent = index != -1 && 
     (index == 0 || partEmails[index - 1] == ',') && 
     (index + email.Length == partEmails.Length || partEmails[index + 1] == ','); 

    if (!isAlreadyPresent) 
    { 
     partEmails += "," + email; 
    } 
} 

part[Constants.Emails] = partEmails; 
3

は、あなたの代わりに単一の大きなstringHashSetを使用することはできますか?リストに値が存在しない場合は、リストに値が追加されます。例えば。

part[Constants.Emails] = new HashSet<string>(); 
foreach (var email in oEmails) 
    part[Constants.Emails].Add(email); 

大きな文字列との変換が簡単に必要な場合は、クラスを作成することができます。

class Emails : HashSet<string> 
{ 
    public Emails(string concatenatedList) 
     : base(concatenatedList.Split(',')) 
    { 
    } 
    public override string ToString() 
    { 
     return string.Join(",", this); 
    } 
} 
+0

+1より高いレベルのアプローチを使用します。 –

+0

合意していますが、これはすぐにLINQにジャンプせず、組み込み型を簡単/効率的に使用するいくつかのアプローチの1つです。 – SPFiredrake

0

これを試してみてください:

part[Constants.Emails] = string.Join(",", ( 
    from e in (part[Constants.Emails].ToString() + "," + orderEmails).Split(',') 
    where !string.IsNullOrEmpty(e) 
    select e 
).Distinct().ToArray()); 

それは読みにくくだが、おそらくはるかに高速に実行されます。

EDIT:他のほとんどのソリューション(質問を含む)は、文字列連結を使用します。 StringBuilderはこれにはるかに優れています。

EDIT:リストまたはハッシュテーブルとして、このデータを格納するは、カンマ区切りの文字列に結果の配列/リストをconcatinatingとアウトバックするたびに、それを解析するよりもはるかに優れている、1つが間違った答えを得るには何も言いませんあなたの弦の中に正当なカンマが入っていました。

+0

特に「Distinct」を使用している場合、なぜ高速になりますか? –

0

あなたはこのようにロジックを統合することができるはずです。

oEmails.Where(partEmails.Contains).Select(e => partEmails[Constants.Emails] += string.Format(",{0}", e)); 
+0

"[email protected]"を追加していて、既に "[email protected]"がある場合、 "[email protected]"は追加されません。 – robrich

+1

@robrich:これは 'String.Contains'ではなく' List.Contains'なので、真実ではありません。私は3人がこれまで読解ミスをしたことに驚いています。 :D –

+0

@robrich:Tomが正しいです。これは、リスト内の項目に対して完全一致を行います。あなたがdownvoterだったら、私はそれを固定していただければ幸いです。 –

0

たぶん、あなたは配列でやっているつもりです

 

var result = oEmails.Select((x, i) => oEmails[i] == partEmails[i] ? part[Constants.Emails] : 
      partEmails.Contains(x) ? part[Constants.Emails] : -1).ToArray(); 
 
+0

これらの三項条件は本当に論理をあいまいにしています... –

関連する問題