4

C#初心者として、現在、文字列内の最初の大文字のインデックスを見つけるために、私は方法を見つけました

var pos = spam.IndexOf(spam.ToCharArray().First(s => String.Equals(s, char.ToUpper(s))));

機能的には、コードは問題なく動作しますが、文字列を 2 回走査するという不快感がありました。LINQ を使用して 1 回のパスで最初の UpperCase 文字のインデックスを取得する可能性はありますか?

C ++での同等の方法は次のようになります

std::string::const_iterator itL=find_if(spam.begin(), spam.end(),isupper);

同等の Python 構文は次のようになります。

next(i for i,e in enumerate(spam) if e.isupper())
4

7 に答える 7

7

でやりたいだけならLINQ、次のようなものを試すことができます

(from ch in spam.ToArray() where Char.IsUpper(ch) 
         select spam.IndexOf(ch))

これを文字列に対して実行すると、

"string spam = "abcdeFgihjklmnopQrstuv";"

結果は次のようになります5, 16

これにより、期待される結果が返されます。

于 2012-04-21T09:36:08.137 に答える
3

別の可能性:

string s = "0123aBc";
int rslt = -1;
var ch = s.FirstOrDefault(c => char.IsUpper(c));
if (ch != 0)
    rslt = s.IndexOf(ch);

また、英語のみに関心がある場合は、次のようになります。

char[] UpperCaseChars = new char[] 
{
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
    'Y', 'Z'
};
int rslt = s.IndexOfAny(UpperCaseChars);

これはおそらく他のどの方法よりもはるかに高速に実行されるため、これを頻繁に実行する場合はこれを使用します。

もう 1 つの可能性は、正規表現を使用することです。

var match = Regex.Match(s, "\p{Lu}", RegexOptions.None);
int rslt = match.Success ? match.Index : -1;

これは、すべての Unicode 大文字に一致します。英語だけが必要な場合は、式を に変更し"[A-Z]"ます。

于 2013-04-19T12:05:59.630 に答える
2

LINQ は必要ありません:

int index = 0;
foreach(Char c in myString)
{
   if(Char.IsUpper(c)) break;
   index++;
}

// index now contains the index of the first upper case character

これは、@Tigran のコメントのように、拡張メソッドに簡単に変換できます。

于 2012-04-21T09:24:16.367 に答える
2

人々が知らないことがよくあるという理由だけで:

Select には、列挙している項目だけでなく、インデックスも取得する方法があります。わずかに余分なオーバーヘッドが発生しますが、これを行うことができます:

var objectsWithCharAndIndex = myString.Select((c,i)=>new {Char = c,Index = i});

次に、それを行うだけの問題です:

var firstCapitalIndex = objectsWithCharAndIndex.First(o => Char.IsUpper(o.Char)).Index;

またはそれらすべてを返します

var allCapitalIndexes = objectsWithCharAndIndex.Where(o => Char.IsUpper(o.Char)).Select(o=>o.Index);

文字とインデックスが一緒に必要な場合は、オブジェクトを反復処理できます。

これは通常の Linq 構文であり、Linq クエリ構文ではありません。

于 2013-04-19T11:39:37.037 に答える
2

@Tigran に基づく回答を次に示しますが、重複がある場合でも、すべての大文字のインデックスが返されます。

from i in Enumerable.Range(0, searchText.Length - 1) 
      where Char.IsUpper(searchText.Chars[i]) select i
于 2013-04-19T11:07:21.077 に答える