2015-12-20 2 views
13

は、コードを見てみましょう:クエリ結果に1文字が表示されないのはなぜですか?

string expression = "x & ~y -> (s + t) & z"; 
var exprCharsNoWhitespace = expression.Except(new[]{' ', '\t'}).ToList(); 
var exprCharsNoWhitespace_2 = expression.Replace(" ", "").Replace("\t", "").ToList(); 

// output for examination 
Console.WriteLine(exprCharsNoWhitespace.Aggregate("", (a,x) => a+x)); 
Console.WriteLine(exprCharsNoWhitespace_2.Aggregate("", (a,x) => a+x)); 

// Output: 
// x&~y->(s+t)z 
// x&~y->(s+t)&z 

は、私は元の文字列からすべての空白を削除して、個々の文字を取得したいです。 結果は私を驚かせました。 変数exprCharsNoWhitespaceには、期待どおりに空白は含まれませんが、予期せず、、ほとんどの文字のみが含まれています。最後の出現は '&'です。リストのCountは12です。 exprCharsNoWhitespace_2は完全に期待どおりですが、Countは13で、空白以外のすべての文字が含まれています。

フレームワークは.NET 4.0でした。 私はこれをcsharppad(WebベースのIDE /コンパイラ)に貼り付けて同じ結果を得ました。

どうしてですか?


EDIT: オールライトライアン・オハラ、集合演算で指摘したように、私は、除いてであることを知りませんでした。私はこれまでこれを使用していませんでした。

// So I'll continue just using something like this: 
expression.Where(c => c!=' ' && c!='\t') 

// or for more characters this can be shorter: 
expression.Where(c => ! new[]{'a', 'b', 'c', 'd'}.Contains(c)). 

答えて

18

Except produces a set difference.あなたの式は集合ではないので、使用する権利の方法ではありません。 &が特に欠けている理由については、それが繰り返されているからです。他の文字はありません。

+2

D'OH!私はその方法の側面を知らなかった。 – user1847129

+0

うわー、これはひどい命名です。私はこれを期待したことはなかっただろう。 – Mehrdad

+0

@Mehrdad - ここで命名を修正するためにあなたは何をしたいのですか? Enumerableには、多くの「セットベース」のメソッドがあり、従来のセット用語であるIntersect、Union、Exceptを使用しています。 –

4

Ryanは既にあなたの質問に答えてくれましたが、あなたに直面している問題の代替ソリューションを提供したいと思います。多くの文字列操作を行う必要がある場合は、正規表現パターンマッチングが役立つことがあります。むしろそれを作成するよりも、どこかに保存された正規表現オブジェクトを保管してください

string pattern = "[abcd]"; 

string expression = "x & ~y -> (s + t) & z"; 
string pattern = @"\s"; 
string replacement = ""; 
string noWhitespace = new Regex(pattern).Replace(expression, replacement); 

または第二例えば、パターン以外同じにすべてを保つ:あなたが与えてくれた例は、このような何かを働くだろうあなたは同じパターンをたくさん使うつもりなら毎回。

3

既に言及したように、.Except(...)はセット操作で重複を削除します。

は、だけではなく、.Where(...)を使用してみてください:

string expression = "x & ~y -> (s + t) & z"; 
var exprCharsNoWhitespace = 
    String.Join(
     "", 
     expression.Where(c => !new[] { ' ', '\t' }.Contains(c))); 

これは与える:

x&~y->(s+t)&z 
関連する問題