Edited at

PHPのアレはRubyで書くとコレ

More than 3 years have passed since last update.

最近、PHPで書かれたコードをRubyに移行している。

(CodeIgniter => Rails)

で、あのコードはどう書くんだろうという奴をつらつらとメモってみる。

※同じ挙動をするという点を今は大事にしているのでRubyらしさは後から。


前提

PHP 5.4 => Ruby 2.0.0

Rails 3.2.x


配列周り

<?php

// 代入
$ids = [];
$ids[] = 1;
$ids[] = 2;
$ids[] = 3;
$ids[] = 4;
$ids[] = 1;

// イテレーション
foreach ($ids as $id) {
echo "id => {$id}\n";
}

// unique
$ids = array_unique($ids);

# 代入

ids = []
ids << 1
ids << 2
ids << 3
ids << 4
ids << 1

# イテレーション
ids.each do |id|
puts "#{id}"
end

ids.map {|id| puts "#{id}"}

ids.map(&method(:puts))

# unique
ids.uniq!


ハッシュ

<?php

$items = [
"key1" => "value1",
"key2" => "value2",
"key3" => "value3"
];

// イテレーション
foreach ($items as $key => $value) {
echo "{$key} => {$value}\n";
}

// イテレーション2
foreach ($items as $value) {
echo "{$value}\n";
}

# シンボル使ってるから厳密には違う

# 大抵、この後JSONにするから問題にならない
items = {
key1: "value1",
key2: "value2",
key3: "value3"
}

# イテレーション
items.each do |key, value|
puts "#{key} => #{value}"
end

# イテレーション2
items.each_value do |value|
puts "#{value}"
end


ループ

<?php

// continue
foreach ($ids as $id) {
if ($id % 2 == 0) continue;
echo "id => {$id}\n";
}

# continue

ids.each do |id|
next if id.even?
puts "id => #{id}"
end


よくやっている処理

<?php

// idをキーにして配列を初期化しておく
$results = [];
foreach ($ids as $id) {
$results[$id] = false;
}

// user_idだけ取りたい
$user_ids = [];
foreach ($users as $user) {
$user_ids[] = $user->id;
}

// user_idだけ取りたい2
$user_ids = array_map(function($v) { return $v->id; }, $users);

// user_idをキーにしたい
$results = [];
foreach ($users as $user) {
$results[$user->id] = $user;
}

# idをキーにして配列を初期化しておく

results = {} # PHPの頃の癖で[]にしておかしくなる事が何度も…。
ids.each do |id|
results[id] = false
end

ids.each_with_object({}) {|id, h| h[id] = false }

results = ids.inject({}) {|h, id| h[id] = false; h }

results = {}.tap {|h| ids.map {|id| h[id] = false}}

# user_idだけ取りたい
user_ids = users.map {|user| user.id }
user_ids = users.map(&:id)

# user_idをキーにしたい(ActiveSupport)
results = users.index_by(&:id)