LoginSignup
0
0

More than 5 years have passed since last update.

複数回キーワードが出現するシーケンスを塊で取得する(Linq)

Posted at

目的

1ファイルの中に特定の文字列をキーワードにして、取得を行いたい。。。
キーワードが1つだけなら、SkipWhile()拡張メソッドで対応できるけど、キーワードが複数回出現する場合だと対応できなくなってしまうので、それなら作ってしまおうということで作ってみた。

使用環境

言語 : C#

実際のソース

IoUtil.cs
using System;
using System.Collections.Generic;
using System.Linq;

    public static class IoUtil
    {
        /// <summary>
        /// キーワードが出てきたら次のキーワードが出てくるまでのシーケンスを返す
        /// </summary>
        /// <param name="fileText">入力ソース</param>
        /// <param name="keyword">キーワード</param>
        /// <returns>キーワードの行を除いたシーケンス</returns>
        public static IEnumerable<IEnumerable<string>> RepeatSkipToKeyword(this IEnumerable<string> fileText, string keyword)
        {
            // データがなければ終了
            if (!fileText.Any())
            {
                yield break;
            }

            while (fileText.Any())
            {
                var text = fileText.SkipWhile(x => !x.Contains(keyword)).Skip(1);
                var targetText = text.TakeWhile(x => !x.Contains(keyword));
                yield return targetText;
                fileText = text.SkipWhile(x => !x.Contains(keyword));
            }
        }
    }

これで、一応キーワードが出現したところから次のキーワードまでを取得することができたので、サンプルも書いてみる。

実際に動かしてみた

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            var stringList = new List<string>();
            string keyword = "keyword";

            stringList.Add("hoge");
            stringList.Add(keyword);
            stringList.AddRange(Enumerable.Range(1, 10).Select(x => x.ToString()));
            stringList.Add(keyword);
            stringList.AddRange(Enumerable.Repeat("これはサンプル", 13));
            stringList.Add(keyword);
            stringList.Add("hoge");

            Console.WriteLine($"{new string('-', 30)}そのまま表示{new string('-', 30)}");
            foreach (var oneLine in stringList)
            {
                Console.WriteLine(oneLine);
            }

            Console.WriteLine($"{new string('-', 30)}使ってみた時の表示{new string('-', 30)}");
            foreach (var oneLine in stringList.RepeatSkipToKeyword(keyword).SelectMany(x => x))
            {
                Console.WriteLine(oneLine);
            }

        }
    }

サンプルを使用したときの戻り値はシーケンスで取得されるので、SelectMany()拡張メソッドを使用して平坦化した。
実行するとこんな感じ

output.txt
------------------------------そのまま表示------------------------------
hoge
keyword
1
2
3
4
5
6
7
8
9
10
keyword
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
keyword
hoge
------------------------------使ってみた時の表示------------------------------
1
2
3
4
5
6
7
8
9
10
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
これはサンプル
hoge

こんな感じで、foreachで回すことができる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0