はじめに
プログラミングでは、配列がデータベースのような構造(ハッシュの配列/連想配列の配列)になっていることがよくあります。このブログでは、そのような構造から特定の条件に一致するデータを効率的に検索・抽出する方法を、Ruby と PHP の両方で解説します。
直接フィルタリング
まず、最もシンプルな方法として、配列から直接条件に一致するデータをフィルタリングする方法を見てみましょう。
Ruby での実装
Ruby では、each メソッドまたは select メソッドを使用して直接フィルタリングができます:
data = [
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
{ name: "Alice", age: 28 },
{ name: "Charlie", age: 35 }
]
# each メソッドを使用する方法
filtered_data = []
data.each do |row|
filtered_data << row if row[:name] == "Alice"
end
puts filtered_data
# => [{:name=>"Alice", :age=>30}, {:name=>"Alice", :age=>28}]
# select メソッドを使用する方法
filtered_data = data.select { |row| row[:name] == "Alice" }
puts filtered_data
# => [{:name=>"Alice", :age=>30}, {:name=>"Alice", :age=>28}]
PHP での実装
PHP では、foreach ループまたは array_filter 関数を使用して同様のフィルタリングができます:
$data = [
['name' => 'Alice', 'age' => 30],
['name' => 'Bob', 'age' => 25],
['name' => 'Alice', 'age' => 28],
['name' => 'Charlie', 'age' => 35]
];
// foreach ループを使用する方法
$filtered_data = [];
foreach ($data as $row) {
if ($row['name'] === 'Alice') {
$filtered_data[] = $row;
}
}
print_r($filtered_data);
// 出力: Array ( [0] => Array ( [name] => Alice [age] => 30 ) [1] => Array ( [name] => Alice [age] => 28 ) )
// array_filter 関数を使用する方法
$filtered_data = array_filter($data, function($row) {
return $row['name'] === 'Alice';
});
// キーをリセット(オプション)
$filtered_data = array_values($filtered_data);
print_r($filtered_data);
複数条件でのフィルタリング
次に、複数の条件を指定してフィルタリングする方法を見てみましょう。
Ruby での実装
data = [
{ name: "Alice", age: 30, city: "Tokyo" },
{ name: "Bob", age: 25, city: "Osaka" },
{ name: "Alice", age: 28, city: "Tokyo" },
{ name: "Charlie", age: 35, city: "Tokyo" }
]
# name が "Alice" かつ age が 29 以下のデータを抽出
filtered_data = data.select do |row|
row[:name] == "Alice" && row[:age] <= 29
end
puts filtered_data
# => [{:name=>"Alice", :age=>28, :city=>"Tokyo"}]
PHP での実装
$data = [
['name' => 'Alice', 'age' => 30, 'city' => 'Tokyo'],
['name' => 'Bob', 'age' => 25, 'city' => 'Osaka'],
['name' => 'Alice', 'age' => 28, 'city' => 'Tokyo'],
['name' => 'Charlie', 'age' => 35, 'city' => 'Tokyo']
];
// name が "Alice" かつ age が 29 以下のデータを抽出
$filtered_data = array_filter($data, function($row) {
return $row['name'] === 'Alice' && $row['age'] <= 29;
});
$filtered_data = array_values($filtered_data);
print_r($filtered_data);
グループ化(Group By)
データベースの GROUP BY 句のように、特定のキーでデータをグループ化する方法です。
Ruby での実装
Ruby では、group_by メソッドを使って簡単にグループ化できます:
data = [
{ name: "Alice", age: 30, city: "Tokyo" },
{ name: "Bob", age: 25, city: "Osaka" },
{ name: "Charlie", age: 35, city: "Tokyo" },
{ name: "Dave", age: 28, city: "Osaka" }
]
# city ごとにグループ化
grouped_by_city = data.group_by { |row| row[:city] }
puts grouped_by_city
# => {
# "Tokyo"=>[{:name=>"Alice", :age=>30, :city=>"Tokyo"}, {:name=>"Charlie", :age=>35, :city=>"Tokyo"}],
# "Osaka"=>[{:name=>"Bob", :age=>25, :city=>"Osaka"}, {:name=>"Dave", :age=>28, :city=>"Osaka"}]
# }
PHP での実装
PHP では組み込みのグループ化関数がないため、ループを使って実装します:
$data = [
['name' => 'Alice', 'age' => 30, 'city' => 'Tokyo'],
['name' => 'Bob', 'age' => 25, 'city' => 'Osaka'],
['name' => 'Charlie', 'age' => 35, 'city' => 'Tokyo'],
['name' => 'Dave', 'age' => 28, 'city' => 'Osaka']
];
// city ごとにグループ化
$grouped_by_city = [];
foreach ($data as $row) {
$city = $row['city'];
if (!isset($grouped_by_city[$city])) {
$grouped_by_city[$city] = [];
}
$grouped_by_city[$city][] = $row;
}
print_r($grouped_by_city);
ソート(Order By)
特定のキーを基準にしてデータを並び替える方法です。
Ruby での実装
Ruby では、sort_by メソッドを使って簡単にソートできます:
data = [
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
{ name: "Charlie", age: 35 }
]
# age で昇順ソート
sorted_by_age = data.sort_by { |row| row[:age] }
puts sorted_by_age
# age で降順ソート
sorted_by_age_desc = data.sort_by { |row| -row[:age] }
# または
sorted_by_age_desc = data.sort { |a, b| b[:age] <=> a[:age] }
puts sorted_by_age_desc
PHP での実装
PHP では、usort 関数を使ってカスタムソートを実装します:
$data = [
['name' => 'Alice', 'age' => 30],
['name' => 'Bob', 'age' => 25],
['name' => 'Charlie', 'age' => 35]
];
// age で昇順ソート
usort($data, function($a, $b) {
return $a['age'] <=> $b['age'];
});
print_r($data);
// age で降順ソート
usort($data, function($a, $b) {
return $b['age'] <=> $a['age'];
});
print_r($data);
結合(JOIN)
2つの配列をキーで結合(リレーショナルデータベースの JOIN に相当)する方法です。
Ruby での実装
users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" }
]
posts = [
{ id: 101, user_id: 1, title: "Ruby の基礎" },
{ id: 102, user_id: 1, title: "PHP の基礎" },
{ id: 103, user_id: 2, title: "Rails 入門" }
]
# user_id をキーにして結合
joined_data = posts.map do |post|
user = users.find { |u| u[:id] == post[:user_id] }
post.merge(user_name: user ? user[:name] : nil)
end
puts joined_data
PHP での実装
$users = [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob']
];
$posts = [
['id' => 101, 'user_id' => 1, 'title' => 'Ruby の基礎'],
['id' => 102, 'user_id' => 1, 'title' => 'PHP の基礎'],
['id' => 103, 'user_id' => 2, 'title' => 'Rails 入門']
];
// 高速化のために users を id でインデックス化
$users_by_id = array_column($users, null, 'id');
$joined_data = array_map(function($post) use ($users_by_id) {
$userId = $post['user_id'];
$userName = isset($users_by_id[$userId]) ? $users_by_id[$userId]['name'] : null;
return array_merge($post, ['user_name' => $userName]);
}, $posts);
print_r($joined_data);
まとめ
Ruby と PHP での配列データベース構造の操作テクニックを比較しました。
Ruby は組み込みのコレクションメソッド(select, group_by, sort_by 等)が非常に強力で直感的に書けます。
一方、PHP も array_filter や usort、array_column を組み合わせることで柔軟かつ高速に配列データを操作できます。
用途に合わせて最適なアプローチを選びましょう。