dthy
@dthy (dorrrothy)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

IndexOfメソッドで二回目に出てきたものの位置

解決したいこと

string str = "Qiita";
int index = str.IndexOf("i");

上のコードでは先頭から最初に見つけた"i"の場所で1が返ってきますが

最初の"i"を飛ばして次に見つけた"i"の場所を取るやり方を教えていただきたいです。
=この場合2を返したい

自分で試したこと

最初に見つけた文字を消せばいけなくもなかったんですけど後々にその文字列をそのまま使いたいので
できれば文字列を消さないやり方を教えてほしいです。

1

4Answer

要求を「n番目のインデックスが欲しい」と受け取ってみました。

var str = "Qiita";
var index = str.IndexOfTimes("i", 2);
public static class IndexOfTimesHelper {
    /// <summary>指定された文字列が対象の文字列内でtimes番目に見つかった位置を返します。</summary>
    /// <param name="str">探索の対象</param>
    /// <param name="key">発見すべきもの</param>
    /// <param name="times">回数 (1~)</param>
    /// <returns>発見された0から始まるインデックス位置</returns>
    public static int IndexOfTimes (this string str, string key, int times) {
        var index = -1;
        for (var i = 0; i < times; i++) {
            if ((index = str.IndexOf (key, index + 1)) < 0) break;
        }
        return index;
    }
}
0Like

Comments

  1. @dthy

    Questioner

    回答ありがとうございます。
    参考にしてみます!

LINQでこんなのはどうでしょう?

using System;
using System.Linq;

class Program {
    static void Main(string[] args) {
        string str = "Qiita";
        int index = str.Select((c, i) => (c, i))
                       .Where(_ => _.c == 'i')
                       .Skip(1)
                       .First()
                       .i;
        Console.WriteLine(index);
        // 2
    }
}
0Like

Comments

  1. @dthy

    Questioner

    回答ありがとうございます。
    参考にしてみます!

見つけた位置の次からもう一度検索すれば良いんじゃないでしょうか。

str.indexOf("i", str.indexOf("i") + 1)
0Like

Comments

  1. @dthy

    Questioner

    こういう使い方があるのを知りませんでした。
    ありがとうございます。

小難しいことをするとこんな感じですかね。

class Program
{
    static void Main(string[] args)
    {
        string str = "Qiita";

        var indexes = str.IndexesOf("i");
        if (indexes.Count() > 1)
        {
            int index = indexes.ElementAt(1);
            Console.WriteLine($"get at {index}");
        }
    }
}

static class StringHelper
{
    public static IEnumerable<int> IndexesOf(this string entry, string value)
    {
        int index = 0;
        while(index >= 0)
        {
            index = entry.IndexOf(value, index);
            if (index >= 0)
                yield return index++;
        }
    }
}
0Like

Comments

  1. @dthy

    Questioner

    回答ありがとうございます。
    参考にしてみます!

Your answer might help someone💌