Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
List とは何か? / PHPerKaigi 2025
Search
meihei
March 28, 2025
Programming
1.7k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
List とは何か? / PHPerKaigi 2025
https://fortee.jp/phperkaigi-2025/proposal/04d840aa-6baa-4f57-8d63-54e4f446e069
meihei
March 28, 2025
More Decks by meihei
See All by meihei
隙間ツール開発のすすめ / PHP Conference Fukuoka 2025
meihei3
0
1.2k
QRコードを学んで遊ぼう / php-study-177
meihei3
0
220
改めて学ぶ Trait の使い方 / phpcon odawara 2025
meihei3
1
2k
WebアプリケーションにおけるPDOの使い方入門 / phpcon odawara 2024
meihei3
3
2.7k
PHPerライフをChrome拡張開発でちょっと便利に / PR TIMES x DMM.com
meihei3
0
480
ファイルを選択してZIPダウンロードする機能ってどうやって作るの? / phpcondo 2023
meihei3
1
920
New Relic CodeStreamを 使って、エラーを 加速的迅速に改修しよう! #NRUG Vol.8
meihei3
0
450
PHP8.2から見る、2つの配列 / PHP Conference Japan 2023
meihei3
0
2.6k
良いコードを書く 〜10年後のPR TIMESを作る〜 / LT会 in #PRTIMES_HACKATHON 2023
meihei3
2
290
Other Decks in Programming
See All in Programming
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
250
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
200
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
540
New "Type" system on PicoRuby
pocke
1
920
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.1k
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
3.9k
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
140
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
480
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
13
4.2k
Vite+ Unified Toolchain for the Web
naokihaba
0
300
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
141
7.5k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
The browser strikes back
jonoalderson
0
1.2k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
360
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
160
Evolving SEO for Evolving Search Engines
ryanjones
0
220
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
390
Visualization
eitanlees
152
17k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
Leo the Paperboy
mayatellez
7
1.8k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
180
Transcript
© 2012-2025 BASE, Inc. 1 #phperkaigi #a List とは何か? PHPerKaigi
2025(2025/03/23)
© 2012-2025 BASE, Inc. 2 © 2012-2025 BASE, Inc. 2
これだけ覚えて帰ってください
© 2012-2025 BASE, Inc. 3 #phperkaigi #a リスト(List)とは キーが0から始まる 連続した整数である配列
© 2012-2025 BASE, Inc. 4 #phperkaigi #a 自己紹介 meihei |
Yohei Ema BASE株式会社 BASE / Product Dev / Feature Dev 1 X: @app1e_s mixi2: @meihei2 GitHub: @meihei3
© 2012-2025 BASE, Inc. 5 1 2 3 #phperkaigi #a
仕様から見たリスト 静的解析ツールから見たリスト PHPの処理から見たリスト 3つの視点からお話しします
© 2012-2025 BASE, Inc. 6 © 2012-2025 BASE, Inc. 6
仕様から見たリスト
© 2012-2025 BASE, Inc. 7 #phperkaigi #a 配列がリストである = array_is_list()
が TRUE である
© 2012-2025 BASE, Inc. 8 #phperkaigi #a RFC を読むと •
PHP RFC: Add array_is_list(array $array): bool • リスト型を導入するわけではなく、配列が0から始まる連続した整数キーで あるかどうかを判定する関数を追加するだけ • (背景)PHPの配列は、整数キーと文字列キーの両方を持つことができ、 かつその順序が保証されている ◦ [0 => 0, 1 => 1, 2 => 2] と [0 => 0, 2 => 2, 1 => 1] は異なる • (使用例)エンコーダなどで効率的にリストを判定したい時に使う ◦ [0 => 0, 1 => 1, 2 => 2] ならば ‘[0, 1, 2]’ に ◦ [0 => 0, 2 => 2, 1 => 1] ならば ‘{“0”: 0, “2”: 2, “1”: 1}’ に
© 2012-2025 BASE, Inc. 9 #phperkaigi #a 配列がリストである例 ['りんご', 'みかん',
'バナナ'] キーをすべて省略した配列 [0 => 'りんご', 1 => 'みかん', 2 => 'バナナ'] キーが0から始まる連続した整数を明 示的にした配列 [false => 'りんご', true => 'みかん', '2' => 'バナナ'] キーが0から始まる連続した整数とみ なせる値の配列 [] 空配列 ['りんご', 1, 2, null, []] 値が何であっても、キーがリストであ る要件をみたす配列
© 2012-2025 BASE, Inc. 10 #phperkaigi #a 配列がリストではない例 [1 =>
'みかん', 2 => 'バナナ'] 連続した整数キーが0から始まらない 配列 ['りんご', 'みかん', 99 => 'かまぼこ'] 整数キー連続していない配列 ['a' => 'apple', 'b' => 'banana'] キーが整数ではない文字列の配列
© 2012-2025 BASE, Inc. 11 #phperkaigi #a リストを返す配列関数(よく使うもの) array_keys, array_values,
range 常にリストを返す array_chunk preserve_keys が false ならリスト を返す array_column index_key を指定しないならリストを 返す array_merge, array_map, array_slice, array_reverse 入力がリストならリストを返す
© 2012-2025 BASE, Inc. 12 #phperkaigi #a 配列がリストであるかは array_is_list() を使って
実行時に判定する
© 2012-2025 BASE, Inc. 13 #phperkaigi #a 関数呼び出し時にリストか判定する $a =
[ 0 => 'りんご', 3 => 'ぶどう', 1 => 'みかん', 2 => 'バナナ', ]; echo array_is_list($a); // FALSE unset($a[3]); echo array_is_list($a); // TRUE 1回目の呼び出し時は、キーが 0,3,1,2 の順になるからリストではな い。 2回目の呼び出し時は、キーが 0,1,2 の順になるからリストとなる。
© 2012-2025 BASE, Inc. 14 © 2012-2025 BASE, Inc. 14
静的解析ツールから見たリスト
© 2012-2025 BASE, Inc. 15 #phperkaigi #a 配列がリストである = list<T>
で表される配列
© 2012-2025 BASE, Inc. 16 #phperkaigi #a リスト型 • PHPの仕様上、リスト型は無い
• 静的解析ツールではPHPDoc上で扱う擬似的な型としてリスト型がある • list<T> は array<int, T> のサブタイプとして定義される ◦ list<T> は、配列が array<int, T> であることに加えて、キーが0から始まる連続し た整数である配列 • 配列がリストであるかを、より厳格に型としてチェックできる
© 2012-2025 BASE, Inc. 17 #phperkaigi #a 静的解析ツールによる型チェック /** *
@param list<string> $x **/ function hello(array $x): void {...} $a = ['りんご', 'みかん', 99 => 'かまぼこ']; hello($a); // Error: Parameter #1 $x of function hello expects list<string>, array{0: 'りんご', 1: ' みかん', 99: 'かまぼこ'} given. PHPを実行する分にはエラーは発生し ない。 静的解析ツールを使うと、厳格に配列 とリストを区別するので、エラーが発 生する(PHPStan Level 5)。
© 2012-2025 BASE, Inc. 18 #phperkaigi #a インライン @var タグもチェックする
/** @var list<string> $a **/ $a = [ 0 => 'りんご', 1 => 'みかん', 99 => 'かまぼこ', ]; // Error: PHPDoc tag @var with type list<string> is not subtype of native type array{0: 'りんご', 1: 'みかん', 99: 'かまぼこ'}. コードの途中でローカル変数を定義す る場合でも、list<T> 型をチェックし てくれる(PHPStan 1.10, Level 2)。 以前は負の整数のキーに非対応だった が、つい先々週修正された。 phpstan/phpstan#12708 phpstan/phpstan-src#3870
© 2012-2025 BASE, Inc. 19 © 2012-2025 BASE, Inc. 19
PHPの処理から見たリスト
© 2012-2025 BASE, Inc. 20 #phperkaigi #a Packed Array かつ空き領域
(holes)を含んでいない配列 ならば 配列がリストである
© 2012-2025 BASE, Inc. 21 #phperkaigi #a PHPの配列は2つある Hash Table
• キーからハッシュ表を 使ってデータアクセス する • 連想配列を実装する Packed Array • 純粋な配列としてデータ アクセスする • メモリ効率が良く処理が高速
© 2012-2025 BASE, Inc. 22 #phperkaigi #a Packed Array とリスト
• Packed Array は、配列のキーが0から始まる連続した整数である時に 自動的に最適化された配列の内部構造 • 基本的にはリストと条件が同じである • しかし、unset などで空き領域(holes)が生まれることがある ◦ その場合も Packed Array では在り続けるので、Packed Array だけどリストではな い状態が生まれる。 • Packed Array から Hash Table へ自動的に変更されることはあるが、 Hash Table から Packed Array への自動的な変更されることはない ◦ リストだけど Packed Array ではない(Hash Table である)状態が存在する 参照: PHP8.2から見る、2つの配列 / PHP Conference Japan 2023 https://speakerdeck.com/meihei3/php-conference-japan-2023
© 2012-2025 BASE, Inc. 23 #phperkaigi #a 配列がリストである多くの場合 // Packed
Array $a = ['りんご', 'みかん', 'バナナ']; echo array_is_list($a); // TRUE 配列のキーが0から始まる連続した整 数であるので、自動的に Packed Array として最適化される。 この状態はメモリ効率が良くて、処理 も高速。
© 2012-2025 BASE, Inc. 24 #phperkaigi #a Packed Array だがリストではない場合
// Packed Array $a = ['りんご', 'みかん', 'バナナ']; unset($a[1]); echo array_is_list($a); // FALSE unset で要素を削除されただけでは、 Hash Table への自動的な変更は行わ れない。 ただ空き領域が生まれる。
© 2012-2025 BASE, Inc. 25 #phperkaigi #a リストだが Packed Array
ではない場合 // Hash Table $a = [ 0 => 'りんご', 3 => 'ぶどう', 1 => 'みかん', 2 => 'バナナ', ]; unset($a[3]); echo array_is_list($a); // TRUE 配列のキーが連番となっていないの で、Hash Table となる。 配列の再生成が行われない限り、 Packed Array から Hash Table へ自 動的に変更されることはない。
© 2012-2025 BASE, Inc. 26 #phperkaigi #a まとめ • リストとは、キーが0から始まる連続した整数である配列
• PHPの仕様では、リスト型は存在せず array_is_list が TRUE で ある配列のことをリストと言う • 静的解析ではリストを list<T> 型として表現する • 内部実装では Packed Array かつ空き領域(holes)を含んでいない配列な らば、配列がリストである • 多くの場合ではリストは高速でメモリ効率も良い • みんなリストを使おう!
© 2012-2025 BASE, Inc. 27 #phperkaigi #a We are hiring!
https://binc.jp/jobs