> CSS・Sass > Sassで配列を使おう|マップ内の値を検索する(カスタム関数の実装例)
Sassで配列を使おう|マップ内の値を検索する(カスタム関数の実装例)

Sassで配列を使おう|マップ内の値を検索する(カスタム関数の実装例)

SassはCSSを効率的に記述するために開発されたメタ言語(拡張言語)です。
Sassについての基礎知識は下記の記事で紹介しています。

Sassにおけるマップ(map)とは、「キー(key)」と「値(value)」のペアを格納するデータ構造のことです。
マップの詳しい解説は下記の記事で紹介しています。

上記の記事で、マップ内のキーを検索する関数・モジュールを紹介しましたが、Sassの標準機能では、マップ内の値を検索する関数・モジュールは用意されていません
PHPであればin_array()関数などでマップ内の検索をすることができますが、SassはCSSの拡張言語として最低限のロジック機能しか提供されていないため、値の検索を行うことができません
この記事では、マップ内の値を検索する方法を紹介します。

結論:カスタム関数を利用する

下記のようなカスタム関数(ユーザー定義関数)を利用すると、連想配列内の値を検索できます。

1階層目のみ検索するカスタム関数(1)

my-map-has-value($map, $target);

1階層のシンプルなマップを対象に、値の有無をtrueまたはfalseで返します。
指定した値が検索値と一致するまで@eachで繰り返して判断しています。

解説

  • $map … 検索対象のマップ。省略不可。
  • $target … 検索したい値。完全一致で判断される。省略不可。
  • 戻り値 … truefalse

scss記述例|カスタム関数の定義

@function my-map-has-value($map, $target) {
// この関数は、指定された値がマップに存在するかどうかを
// 確認し、存在する場合は true を返します。
// 存在しない場合は false を返します。
  @each $key, $value in $map {
    @if $value == $target {
      @return true;
    }
  }
  @return false;
}

scss記述例|カスタム関数の利用

// マップの定義
$settings: (
    color: blue,
    font-size: 16px,
    font-weight: bold
);

// マップの値をチェックする関数の使用例
$result1: my-map-has-value( $settings, blue );
@debug $result1; // 出力 ⇒ true
$result2: my-map-has-value( $settings, "blue" );
@debug $result2; // 出力 ⇒ false|"blue"は文字列なので配列内の値と完全には一致しない。

1階層目のみ検索するカスタム関数(2)

my-map-has-value-list( $map, $target );

1階層のシンプルなマップを対象に、値の有無をtrueまたはfalseで返します。
マップ内の値をリスト化するmap-values()関数を利用し、生成されたリストをindex()で検索します。

解説

  • $map … 検索対象のマップ。省略不可。
  • $target … 検索したい値。完全一致で判断される。省略不可。
  • 戻り値 … truefalse

scss記述例|カスタム関数の定義

@function my-map-has-value-list($map, $target) {
// この関数は、指定された値がマップに存在するかどうかを
// 確認し、存在する場合は true を返します。
// 存在しない場合は false を返します。
    $list: map-values( $map );
    @if type-of($list) == 'list' {
        @return index($list, $target) != null;
    } @else {
        @return false;
    }
}

scss記述例|カスタム関数の利用

// マップの定義
$settings: (
	color: blue,
	font-size: 16px,
	font-weight: bold
);

// マップの値をチェックする関数の使用例
$result1: my-map-has-value-list($settings, blue);
@debug $result1; // 出力⇒true
$result2: my-map-has-value-list($settings, "blue");
@debug $result2; // 出力⇒false|"blue"は文字列なので配列内の値と完全には一致しない。

map-values()関数の動向に注意! 

Dart Sassでは、map-get()map-merge()関数が非推奨となり、マップモジュールへの移行が推奨されています。
このカスタム関数では、map-values()関数を利用しているので、map-values()関数が今後も利用できるか注視していく必要があります。

2階層目移行も検索するカスタム関数

my-map-has-value-deep( $map, $target );

2階層以上のマップ(多次元連想配列)を対象に、値の有無をtrueまたはfalseで返します。

解説

  • $map … 検索対象のマップ。省略不可。
  • $target … 検索したい値。完全一致で判断される。省略不可。
  • 戻り値 … truefalse

scss記述例|カスタム関数の定義

@function my-map-has-value-deep($map, $target) {
// この関数は、指定されたマップにターゲットの値が存在するかをチェックします。
// マップの値は、ネストされたマップも含めてチェックされます。
// 戻り値は、ターゲットの値が存在する場合は true、
// 存在しない場合は false です。
  @each $key, $value in $map {
    @if $value == $target {
      @return true;
    }
    @else if type-of($value) == 'map' {
      @if deep-map-contains-value($value, $target) {
        @return true;
      }
    }
  }
  @return false;
}

scss記述例|カスタム関数の利用

// マップの定義
$settings: (
	color: blue,
	font: (
		size: 16px,
		weight: bold
	),
	layout: (
		margin: 10px,
		padding: 5px
	)
);

// マップの値をチェックする関数の使用例
// 1階層目の値をチェック
$result1: my-map-has-value-deep($settings, blue);
@debug $result1; // 出力⇒true
// 2階層目以降の値をチェック
$result2: my-map-has-value-deep($settings, bold);
@debug $result2; // 出力⇒true
// 2階層目以降の値をチェック
$result3: my-map-has-value-deep($settings, 20px);
@debug $result3; // 出力⇒false

マップの規模に注意!

ネストされたマップ(多次元連想配列)をチェックする関数は非常に強力で有用ですが、マップの階層が深い場合関数の多用には注意が必要です。
Sassはコンパイル時に処理するため、あまりに深いネストや大きなマップを扱うとコンパイル時間が増える可能性があります。

拡張:マップの値からキーを逆引きするカスタム関数

値の存在を確認するだけでなく、「その値がどのキーに対応しているのか」を知りたい場面も多くあります。
リストであれば、index()関数で指定した値のインデックスを得ることができますが、マップではSassの標準関数だけではこれを直接行うことはできません。

下記のようなカスタム関数(ユーザー定義関数)を利用して、連想配列内の値から逆引きでキーを検索してみます。

連想配列の値からキーを逆引きするカスタム関数

my-map-find-key-by-value( $map, $target )

1階層のシンプルなマップを対象に、指定した値のペアとなるキーを返します。
値が検出されない場合はnullを返します。
指定した値が検索値と一致するまで@eachで繰り返して判断しています。
値が複数のキーにまたがって使われている場合でも、最初に一致した1件目のキーしか取得されません。

解説

  • $map … 検索対象のマップ。省略不可。
  • $target … 検索したい値。完全一致で判断される。省略不可。
  • 戻り値 … $targetのペアとなるキー

scss記述例|カスタム関数の定義

@function map-find-key-by-value($map, $target) {
// この関数は、指定された値がマップに存在した場合にキーを返します。
// 存在しない場合は null を返します。
  @each $key, $value in $map {
@if $value == $target {
@return $key;
}
}
@return null; }

scss記述例|カスタム関数の利用

// マップの定義
$settings: (
	color: blue,
	font-size: 16px,
	font-weight: bold
);

// マップの値からキーを取得する関数の使用例
$result1: my-map-find-key-by-value($settings, blue);
@debug $result1; // color
$result2: my-map-find-key-by-value($settings, "blue");
@debug $result2; // null|完全一致しないのでnullになる

まとめ

Sassのマップは、キーと値のペアで構造化された情報を管理できる強力な機能ですが、「値の検索」や「値からキーを逆引きする」といった操作は標準機能としては用意されていません。
しかし、Sassには@function@eachなどの関数があるため、自分自身でカスタム関数を定義することで、こうした標準にない処理も柔軟に実現できます。

カスタム関数は再利用性が高く、プロジェクト全体のスタイル設計の効率や保守性を高める上でも非常に有効です。
マップ操作においても、カスタム関数をうまく活用して、より賢く、スケーラブルなスタイル設計を目指しましょう。

この記事が気に入ったらシェアしてください

関連記事

Sassで配列を使おう|マップ(連想配列)を徹底的に使いこなす!

Sassで配列を使おう|マップ(連想配列)を徹底的に使いこなす!

Sassで配列を使おう|リスト(配列)を徹底的に使いこなす!

Sassで配列を使おう|リスト(配列)を徹底的に使いこなす!

Sassで配列を使おう|リスト(配列)のセパレーターについて考えてみた

Sassで配列を使おう|リスト(配列)のセパレーターについて考えてみた

Sassで配列を使おう|リストとマップの違いをしっかり理解しよう!

Sassで配列を使おう|リストとマップの違いをしっかり理解しよう!

Sassの@if条件分岐をマスターしよう!使い方・応用・注意点まとめ

Sassの@if条件分岐をマスターしよう!使い方・応用・注意点まとめ

Sassでデバッグする方法まとめ|@debug/@warn/@errorの基本と実例

Sassでデバッグする方法まとめ|@debug/@warn/@errorの基本と実例

Comment Form

コメント投稿はこちらをクリックしてください
  • コメントを入力してください。
登録フォーム
Name
Mailaddress
URL
Message
Postkey
(スパム対策に、投稿キー を半角で入力してください。)