0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

1人目が2人目をフォローする、2人目が3人目をフォローする... の様なズレと組み合わせを生成するアルゴリズム[Ruby](zip, rotate)

Last updated at Posted at 2021-06-21

1人目のユーザーが2人目のユーザーをフォローする。
2人目のユーザーが3人目のユーザーをフォローする。...など、
少しずれた関係性を生み出す際に利用可能なアルゴリズムを考えついたのでここで共有します。
2つのメソッドを組み合わせる事で、生成することが可能です。

結論

users = User.all
users.zip(users.rotate) do |following_user, followerd_user|
	following_user.follow(followerd_user)
end

省略形
User.all.zip(User.all.rotate) { _1.follow(_2) }

恐らくこれで動作すると思います!followというtwitterなどで用いられる関係性を生み出す独自メソッドです。省略形はruby2.7以降で動作すると思います!

rotate メソッド

a = [1, 2, 3, 4]
a.rotate         # => [2, 3, 4, 1]
a                # => [1, 2, 3, 4]
a.rotate(2)      # => [3, 4, 1, 2]
a.rotate(-1)     # => [4, 1, 2, 3]

こちらはメソッド名から想像が着くように、引数に渡した数字分だけ配列の要素をズラすメソッドになります。

zip メソッド

p [1, 2, 3].zip(["A", "B", "C"], ["a", "b", "c"])
# => [[1, A, a], [2, "B", "b"], [3, "C", "c"]]

p [1,2].zip([:a,:b,:c], [:A,:B,:C,:D])
# => [[1, :a, :A], [2, :b, :B]]

こちらのメソッドは痒いところに手が届くようなメソッドです。
self配列に対して、引数の配列の同じインデックスに対応する要素を抽出し、それらを組み合わせて新たな配列を生成するメソッドです。
個人的にはメソッド名が好きです。

まとめ

上記2つのメソッドを活用することで、

  1. ズラした配列を生成し、
  2. 元の配列とズラした配列を組み合わせた配列を生成する
  3. 新たな配列に対して、2つの要素を引数に取る繰り返し処理

といった流れで、対応していきます。以下動作反応。

users = User.all
=>   TRANSACTION (0.4ms)  BEGIN
  User Load (15.5ms)  SELECT `users`.* FROM `users`
[#<User id: 1, name: "Test_User1", created_at: "2021-06-20 04:34:55.577201000 +0900", updated_at: "2021-06-20 04:34:56.195767000 +0900">,
 #<User id: 2, name: "Test_User2", created_at: "2021-06-20 04:34:56.513694000 +0900", updated_at: "2021-06-20 04:34:56.607071000 +0900">,
 #<User id: 3, name: "Test_User3", created_at: "2021-06-20 04:34:57.040755000 +0900", updated_at: "2021-06-20 04:34:57.147144000 +0900">,
 #<User id: 4, name: "Test_User4", created_at: "2021-06-20 04:34:57.636523000 +0900", updated_at: "2021-06-20 04:34:57.876562000 +0900"]

users.zip(users.rotate) do |following_user, followerd_user|
	following_user.follow(followerd_user)
end
TRANSACTION (0.4ms)  SAVEPOINT active_record_1
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  Relationship Create (2.4ms)  INSERT INTO `relationships` (`follower_id`, `followed_id`, `created_at`, `updated_at`) VALUES (1, 2, '2021-06-21 13:29:30.279783', '2021-06-21 13:29:30.279783')
	:

余談

これらのメソッドは、Qiitaを通してあるユーザー様にご教授いただきました。
自分の記事に色々とコメントしてくださり、いつも助けられております。
アウトプットする事で視野が広がるいい経験でしたっ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?