指定位置まで要素を読み飛ばす
コレクション操作において、「先頭の5件はヘッダー情報なので無視したい」や「特定の条件を満たすまでの待機データは不要」といったケースがあります。
C#のLINQには、シーケンスの先頭から特定の要素を無視(スキップ)し、残りの要素を取得するための Skip および SkipWhile メソッドが用意されています。
これらは、前回解説した Take / TakeWhile (先頭から取得する)と対になる操作であり、組み合わせて使用されることも多いメソッドです。
Skip(int count):指定した数だけスキップ
Skip メソッドは、シーケンスの先頭から、引数で指定した count 個の要素を無視し、それ以降の残りの要素すべてを返します。
最も一般的な用途は、Webアプリケーションや一覧画面での「ページング(ページ送り)」処理の実装です。
コード例:ページングの実装
1ページあたり3件のデータを表示すると仮定し、3ページ目(7件目~9件目)のデータを取得する例です。
using System;
using System.Collections.Generic;
using System.Linq;
public class PaginationExample
{
public static void Main()
{
// 1から10までの整数リスト (データソース)
var allItems = Enumerable.Range(1, 10).ToList();
int pageSize = 3; // 1ページあたりの件数
int pageNumber = 3; // 取得したいページ番号 (3ページ目)
// 計算ロジック:
// (3ページ目 - 1) * 3件 = 最初の6件をスキップ
// その後、次の3件を取得 (Take)
var pageData = allItems
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize);
Console.WriteLine($"--- ページ {pageNumber} のデータ ---");
Console.WriteLine(string.Join(", ", pageData));
}
}
出力結果:
--- ページ 3 のデータ ---
7, 8, 9
SkipWhile(predicate):条件を満たす間スキップ
SkipWhile メソッドは、シーケンスの先頭から要素を順に評価し、指定した条件(述語)が true である間、要素をスキップし続けます。
条件が一度でも false になると、スキップ処理を終了し、その要素を含めてそれ以降のすべての要素を返します。
コード例:安定稼働までのログをスキップ
サーバーのCPU使用率の時系列データがあり、起動直後のアイドリング状態(使用率が低い状態)を無視し、本格的に負荷がかかり始めてからのデータを抽出する例です。
using System;
using System.Collections.Generic;
using System.Linq;
public class SkipWhileLogExample
{
public static void Main()
{
// CPU使用率の時系列データ
// (起動直後は低く、途中から処理が始まり、最後にまた下がっている)
var cpuLogs = new[] { 5, 8, 12, 45, 80, 30, 10, 5 };
int threshold = 20; // 閾値 (20%以上で稼働とみなす)
// 使用率が20未満の間は「準備中」としてスキップする
// 45 になった時点で条件 (x < 20) が false になり、そこから取得開始
var activeLogs = cpuLogs.SkipWhile(usage => usage < threshold);
Console.WriteLine("--- 稼働開始後のログ ---");
Console.WriteLine(string.Join(" -> ", activeLogs));
}
}
出力結果:
--- 稼働開始後のログ ---
45 -> 80 -> 30 -> 10 -> 5
先頭の 5, 8, 12 は条件(< 20)を満たすためスキップされます。45 で条件が不一致となるため、45 以降のデータ(後半に数値が下がったとしても)はすべて取得されます。
まとめ
Skip と SkipWhile は、シーケンスの「途中から」データを利用したい場合に不可欠なメソッドです。
Skip(n): 固定数(ページングのオフセットなど)でスキップする場合に使用します。SkipWhile(condition): データの状態に基づいて、取得開始位置を動的に決定する場合に使用します。
これらを Take 系メソッドと組み合わせることで、シーケンス内の任意の範囲(スライス)を自由に切り出すことが可能になります。
