2017-09-15 14 views
-1

に登場する同じを開始入手すると、キムは、私は偉大な楽しげに私のダンキンドーナツを食べた蹴り保持しながら」でそれを実行するときにLINQに次のクエリすべての繰り返しが行

select word 
from string1 
where Left(word, 1) in (
    select Left(word, 1) as firstInitial 
    from string1 
    group by Left(word , 1) 
    having count(*) > 1 
) 

を変換する方法はあります

(miss,Match,Match,Match,miss,miss,miss,Match,Match,miss,Match,Match) 

答えて

1

以下の解決策は、1つの可能なアプローチを示しています。これを使用するには、必ずMoreLINQ NuGet packageをプロジェクトに追加してください。

using System; 
using System.Linq; 
using MoreLinq; 

namespace Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var input = "While Kim kept kicking I ate my Dunkin donut with great gusto"; 

      var value = input.Split(' '); 

      var lagged = value.Lag(1, (current, previous) => new { current = current?.ToLowerInvariant(), previous = previous?.ToLowerInvariant() }); 
      var leaded = value.Lead(1, (current, next) => new { next = next?.ToLowerInvariant() }); 

      var results = lagged.Zip(leaded, (x, y) => x.current?.FirstOrDefault() == x.previous?.FirstOrDefault() || 
                 x.current?.FirstOrDefault() == y.next?.FirstOrDefault()); 

      Console.WriteLine(string.Join(",", results)); 
      Console.ReadLine(); 
     } 
    } 
} 

基本的コードが複数の単語に文字列を分割し、各単語(current)を見て、前の単語(previous)及び(next)後。次に、の最初の文字とpreviousの文字とnextの文字を比較します。

あなたは1/0ではなくtrue/falseを返すようにしたい場合は、コードのちょうどこの行を変更:このための解決策は、数行のような単純なものではないでしょうが、私ができる

var results = lagged.Zip(leaded, (x, y) => (x.current?.FirstOrDefault() == x.previous?.FirstOrDefault() || 
              x.current?.FirstOrDefault() == y.next?.FirstOrDefault()) ? 1 : 0); 
+1

ありがとう、mjwills。 – user8595118

1

を試してみてください。

まず、最も単純ではないので、エレガントなforループ方式:

var words = string1.Split(' ').ToList(); 
string[] results = new string[words.Count]; //edited: can use .Count instead of .Count() 
for (int i = 0; i < words.Count; i++) 
{ 
    if (i == words.Count - 1) 
     results[i] = char.ToLower(words[i - 1][0]) == char.ToLower(words[i][0]) ? "Match" : "miss"; 
    else if (i == 0) 
     results[i] = char.ToLower(words[i + 1][0]) == char.ToLower(words[i][0]) ? "Match" : "miss"; 
    else 
    { 
     bool leftMatch = char.ToLower(words[i - 1][0]) == char.ToLower(words[i][0]); 
     bool rightMatch = char.ToLower(words[i + 1][0]) == char.ToLower(words[i][0]); 
     results[i] = (leftMatch || rightMatch) ? "Match" : "miss"; 
    } 
} 

これは、左または右の単語が最初の文字が同じ場合は「一致」、そうでない場合は「ミス」である場合、各要素を通過します。最初と最後の単語について、それはだけではなく、?: Operatorだけでなく、LINQのEnumerable.Range Method (Int32, Int32)を使用して2

の1人の隣人をチェックする必要がある、これは数行に単純化することができます。

var words = string1.Split(' ').ToList(); 
var results = Enumerable.Range(0, words.Count).Select(i => i == words.Count - 1 ? 
     char.ToLower(words[i - 1][0]) == char.ToLower(words[i][0]) ? "Match" : "miss" : 
     i == 0 ? 
     char.ToLower(words[i + 1][0]) == char.ToLower(words[i][0]) ? "Match" : "miss" : 
     (char.ToLower(words[i - 1][0]) == char.ToLower(words[i][0]) || char.ToLower(words[i + 1][0]) == char.ToLower(words[i][0])) ? "Match" : "miss").ToList(); 

ToList()最終的にはオプションです。ご希望の場合はToArray()に変換することができます。

+0

どちらも私にエラーが表示されます:Cs0121 c#次のメソッドまたはプロパティとの間で呼び出しが曖昧です 問題は、整数除算(結果もint)を行い、intを暗黙的にdoubleとdecimalの両方に変換できることです。したがって、式の結果が必ず1つになるようにする必要があります。おそらくダブルはあなたが望むものです。 – user8595118

+0

ありがとうございます、Keyurパテル。ニースのソリューションも。私はあなたからたくさんのことを学んでいます。素晴らしいサイト! – user8595118

関連する問題