[英]C# - Adding indexes of specific chars in a string to a list of integers
尋找有關如何獲取以下代碼以生成longString
中每個空格和連字符的索引列表的longString
。
每當我運行下面的語句時,它只會在我的整數列表中加5。 給定我在以下示例中使用的字符串,我試圖使它收集5、11、14、24和27。
static void Main(string[] args)
{
string longString = "hello world my user-name is stevieray8450";
int longStringLength = longString.Length;
char whiteSpace = ' ';
char hyphen = '-';
// list to store all indexes of white space
List<int> specialIndexes = new List<int>();
foreach (char c in longString)
{
if (c.Equals(whiteSpace) || c.Equals(hyphen))
{
specialIndexes.Add(longString.IndexOf(c));
}
}
我想知道為什么我的foreach
循環中的char c
每次都會對我的specialIndexes.Add(longString.IndexOf(c));
的空格每次求值為5的specialIndexes.Add(longString.IndexOf(c));
聲明。
任何想法,意見,評論歡迎:)謝謝!
您應該改用for循環,以便直接獲取索引:
for(int i =0; i < longString.length; i++)
{
if (longString[i].Equals(whiteSpace) || longString[i].Equals(hyphen))
{
specialIndexes.Add(i);
}
}
當然,有人會為您提供一些LINQ代碼,它們將以更少的代碼完成相同的任務。 等等...
當您的c = ' '
始終為5時, longString.IndexOf(c)
將始終為IndexOf
僅返回其參數首次出現的索引。
public int IndexOf(char value)
如果找到該字符,則從零開始的索引位置,否則為-1。
請記住,char是一個value-type
因此默認情況下,您正在使用副本。
當您調用index時,您將獲得字符串中第一個匹配項的索引
https://msdn.microsoft.com/zh-CN/library/k8b1470s(v=vs.110).aspx
您可以嘗試:
string longString = "hello world my user-name is stevieray8450";
int longStringLength = longString.Length;
char whiteSpace = ' ';
char hyphen = '-';
int index = 0;
// list to store all indexes of white space
List<int> specialIndexes = new List<int>();
foreach (char c in longString)
{
if (c.Equals(whiteSpace) || c.Equals(hyphen))
{
specialIndexes.Add(index);
}
index++;
}
下一行...
specialIndexes.Add(longString.IndexOf(c));
...將返回第一次出現的c的索引,而不是當前的索引。 在示例字符串中,第一個空格或連字符為位置5處的空格。
解決此問題的最佳方法是使用for循環,並將計數器值存儲為索引。
這是因為char
類型是一個值類型,並且IndexOf
返回第一次出現的索引。 就是說,它將返回5作為結果。
您需要將自己的計數器添加到foreach
循環中或在for
循環並在其中使用其索引。
static void Main(string[] args) {
string longString = "hello world my user-name is stevieray8450";
HashSet<char> desiredChars = new HashSet<char> { ' ', '-' };
List<int> specialIndexes = longString
.Select((char, i) => new KeyValuePair<char, int>(char, i))
.Where(kvp => desiredChars.Contains(kvp.Key))
.Select(kvp => kvp.Value)
.ToList();
}
這是您的代碼的另一個版本:
string longString = "hello world my user-name is stevieray8450";
int longStringLength = longString.Length;
char whiteSpace = ' ';
char hyphen = '-';
// list to store all indexes of white space
List<int> specialIndexes = new List<int>();
int index = 0;
do
{
index = longString.IndexOf(whiteSpace, index);
if (index > -1)
{
specialIndexes.Add(index);
index++;
}
} while (index != -1);
我更喜歡可以使用它們的LINQ解決方案。 LINQ的問題在於索引不會結轉到下一條語句。 要了解我的意思,請考慮以下幾點:
var longString = "hello world my user-name is stevieray8450";
var badIndices = longString
.Where(c => c == ' ')
.Select((c, i) => i)
.ToArray();
Console.WriteLine($"[bad!] found ' ' at indices: {string.Join(", ", badIndices)}");
雖然看起來結果應該是5, 11, 14, 24, 27
,但實際結果將是:
[壞!]在索引:0、1、2、3、4處發現了''
為了繼承正確的索引,我們必須即時創建一個中間anonymous type
:
var indices = longString
.Select((c, i) => new
{
idx = i,
val = c
})
.Where(ci => ci.val == ' ')
.Select(ci => ci.idx)
.ToArray();
Console.WriteLine($"[good] found ' ' at indices: {string.Join(", ", indices)}");
一旦習慣了它並沒有那么糟糕,我更喜歡它而不是編寫自己的循環。 結果是:
[good]在指數:5、11、14、24、27處發現了''
但是,在這種特殊情況下, for-loop
效率要高得多,並且完成時間約為LINQ的1/5。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.