【Shopify】LiquidのArray filterを全てまとめてみた話

#はじめに
今回の記事では、shopifyのArray filterを全てまとめてみました。

[こちら](https://shopify.dev/docs/themes/liquid/reference/filters)を参考にしました。
#Array filters
Array filtersを見てみましょう。

liquidの配列に対して適用するフィルターです。

##join
`配列の要素を、パラメーターとして渡された文字と結合します。結果は単一の文字列です。`

パイプの前に配列を指定すると、**`join:`**の後に指定した区切り文字で配列の要素を結合させた**文字列**を返します。

今回の例は、`product.tags (1商品のすべてのタグが要素になっている配列)` が、`[tag1,tag2,tag3]` の場合です。 

各要素である tag1、tag2、tag3 が `,` で結合されて文字列として出力されます。

```.liquid
{{ product.tags | join: ', ' }}
```
>tag1, tag2, tag3

##first
`配列の最初の要素を返します。`


今回の例だと`"sale"`が、配列の一番目の要素なので、`sale`が出力されます。

```.liquid
<!-- product.tags = "sale", "mens", "womens", "awesome" -->
{{ product.tags | first }}
```

>sale

タグ`{%%}`内でフィルター` | `を使用したい場合は、`"配列"."フィルター"`の形で`.` で繋げることで使用できます。


```.liquid
{% if product.tags.first == "sale" %}
  This product is on sale!
{% endif %}
```

上記の例では、`product.tags.first`と指定することで、配列の最初の値である`sale`を出力しています。

##last
`配列の最後の要素を返します。`

指定した配列の最後の要素を返します。

例では、`product.tags` の最後の要素である、`awesome`が出力されています。

```.liquid
<!-- product.tags = "sale", "mens", "womens", "awesome" -->
{{ product.tags | last }}
```

>awesome

firstと同様に、タグのなかでフィルターを使いたいときは `.` で繋げることで使用できます。

```.liquid
{% if product.tags.last == "sale"%}
  This product is on sale!
{% endif %}
```

また、文字列で `last` を使用すると、文字列の末尾の文字が返されます。
下記の例では、文字列の最後の `s` のみが出力されます。

```.liquid
<!-- product.title = "Awesome Shoes" -->
{{ product.title | last }}
```

>s

##concat
`配列を別の配列と連結 (結合) します。結果として得られる配列には、元の配列のすべての要素が含まれます。 concat は、uniq フィルタを使用しない限り、結合された配列から重複した項目を削除しません。`

concatは配列同士を結合するフィルターです。

また、結合する際に重複した項目は削除しません。

```.liquid
{% assign fruits = "apples, oranges, peaches, tomatoes" | split: ", " %}
{% assign vegetables = "broccoli, carrots, lettuce, tomatoes" | split: ", " %}

{% assign plants = fruits | concat: vegetables %}

{{ plants | join: ", " }}
```

>apples, oranges, peaches, tomatoes, broccoli, carrots, lettuce, tomatoes

上記の例では、`assign fruits = "apples, oranges, peaches, tomatoes" | split: ", " `により、文字列を配列に変換しています。

文字列を配列に変換する際に、splitで指定した区切り文字（ここでは`,`）で分割して配列に変換します（今回は`[ apple, oranges, peaches, tomatoes ]`）。

そのあと、`assign plants = fruits | concat: vegetables`で配列同士を結合させています。

最後に、`plants | join: ", "`とすることで、配列を指定した区切り文字（ここでは`,`）で結合した文字列を返します。

また、複数のconcatを用いることで、2つ以上の配列を組み合わせることができます。

```.liquid
{% assign fruits = "apples, oranges, peaches" | split: ", " %}
{% assign vegetables = "broccoli, carrots, lettuce" | split: ", " %}
{% assign animals = "dogs, cats, birds" | split: ", " %}

{% assign things = fruits | concat: vegetables | concat: animals %}

{{ things | join: ", " }}
```

>apples, oranges, peaches, broccoli, carrots, lettuce, dogs, cats, birds

このように、Liquidフィルタは `|` で繋げることで一度に複数のフィルタを使用することができます。

##index
`配列内の指定したインデックス番号の要素を返します。`

配列内の要素にはインデックス番号というものが割り当てられています。

インデックス番号は、0 から始まります。

なので、配列内の一番目の要素をアクセスしたいときは、`product.tags[0]`とするとアクセスできます。

```.liquid
<!-- product.tags = "sale", "mens", "womens", "awesome" -->
{{ product.tags[2] }}
```

 >womens

##map
`配列の属性値（下記例：title）をパラメータに渡すと、配列内のすべての要素を取り出して、一つの文字列を返します。`

下記例では、配列である`collections`に`map: 'title'`を指定することで、`collections`内の`title`属性を持つ値をすべて繋げた文字列（SpringSummerFallWinter）が出力されます。

```.liquid
<!-- collection.title = "Spring", "Summer", "Fall", "Winter" -->
{% assign collection_titles = collections | map: 'title' %}
{{ collection_titles }}
```

>SpringSummerFallWinter


##reverse
`配列内の項目の順序を反転させます。`

```.liquid
{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}

{{ my_array | reverse | join: ", " }}
```

>plums, peaches, oranges, apples

まず、`assign my_array = "apples, oranges, peaches, plums" | split: ", "`の部分で文字列から配列を生成します。

その配列に対して、` my_array | reverse `とすることで、順番を反転させて出力しています。

##size
`文字列であれば文字数、配列であれば要素数を返します。`

```.liquid
{{ 'The quick brown fox jumps over a lazy dog.' | size }}
```

>42

また、タグ`{%%}`の中で`size`を使いたいときは以下のように`.`で繋げます。

```.liquid
{% if collections.frontpage.products.size > 10 %}
  There are more than 10 products in this collection!
{% endif %}
```

上記のようにすると、配列の要素数が10よりも多いときのみ、`There are more than 10 products in this collection!`を表示します。

##sort
`配列の要素を、配列内の要素の指定された属性で並び替えます。`

```.liquid
{% assign products = collection.products | sort: 'price' %}
{% for product in products %}
  <h4>{{ product.title }}</h4>
{% endfor %}
```

上記では、`sort: 'price'`とすることで、コレクション内の商品を価格順で並び替えることができます。

並び替えの順序は、デフォルトで昇順です。

また、配列の並び替えは大文字と小文字を区別します。

先に大文字が昇順で並んで、その後に小文字が昇順で並びます。

```.liquid
<!-- products = "a", "b", "A", "B" -->
{% assign products = collection.products | sort: 'title' %}
{% for product in products %}
   {{ product.title }}
{% endfor %}
```

>A B a b

##where
`whereで指定された属性の値を持った要素の配列を作成します。`

```.liquid
All products:
{% for product in collection.products %}
- {{ product.title }}
{% endfor %}

{% assign kitchen_products = collection.products | where: "type", "kitchen" %}

Kitchen products:
{% for product in kitchen_products %}
- {{ product.title }}
{% endfor %}
```

>All products:
- Vacuum
- Spatula
- Television
- Garlic press

>Kitchen products:
- Spatula
- Garlic press


上記の例では、`assign kitchen_products = collection.products | where: "type", "kitchen"`とすることで、collection.products.typeが`kitichen`である`collection.products`の要素を`kitchen_products`配列に代入しています。

また、`where`を使用する際に、`where: 属性名, 値`を使用せずに、そのままプロパティを指定することができます（`where: 属性`）。その際、プロパティはブーリアン型である必要があります。

```.liquid
{% assign available_products = collection.products | where: "available" %}

Available products:
{% for product in available_products %}
- {{ product.title }}
{% endfor %}
```

上記の例では、`collection.products.available`がブーリアン型であるため、直接プロパティ（属性）を指定して配列を作成することができます。

この場合、`true` のものが代入されます。

##uniq
`配列内の重複した要素を取り除きます。`

```.liquid
{% assign fruits = "orange apple banana apple orange" %}
{{ fruits | split: ' ' | uniq | join: ' ' }}
```

>orange apple banana

上記の例では、`split: ' ' `により、文字列を配列に変換した後、`uniq`により重複した要素を削除しています（今回はorangeとappleが一つずつ削除されます）。


#終わりに
今回の記事はここまでになります。

お疲れさまでした。

# Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://coming-soon.reterior.jp/

https://apps.shopify.com/shopify-application-314?locale=ja&surface_detail=%E3%83%AA%E3%83%86%E3%83%AA%E3%82%A2&surface_inter_position=1&surface_intra_position=1&surface_type=search