Money Forward Developers Blog

株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。

20230215130734

Railsに慣れたRubyistに捧げるUnderscore.js便利メソッド 5選

マネーフォワードではサーバーサイドのエンジニアがRails/JavaScriptともに担当しています。

どうしてもRailsに比べJavaScriptは記述量が気になることが多かったのですが、Underscore.jsを入れてから劇的に便利になりましたので、ご紹介します!

http://underscorejs.org/  

1. where, findWhere

published_books = books.where(published: true)

ActiveRecordを使っているとこのようにとてもシンプルにかける処理ですが、JavaScriptで基本に則って書くと、

var publishedBooks = [];
var l = books.length;

for (var i = 0; i < l; i++) {
  if (books[i].published === true) {
    publishedBooks.push(books[i]);
  }
}

こんな形になるかと思います。 長いですね。。

そんなJavaScriptですが、Underscore.jsを使うと、

var publisedBooks = _.where(books, { published: true });

と、とてもシンプルにかくことができます。

find_byについても同様に、

first_published_book = books.find_by(published: true)
// Underscore.jsなし
var firstPublishedBook;
var l = books.length;

for (var i = 0; i < l; i++) {
  if (books[i].published === true) {
    firstPublishedBook = books[i];
    break;
  } 
}

// Underscore.jsあり
var firstPublishedBook = _.findWhere(books, { published: true });

 

2. keys, values

hash = { key1: "value1", key2: "value" }

keys   = hash.keys
values = hash.values
var hash = { key1: "value1", key2: "value" };

var keys   = _.keys(hash);
var values = _.values(hash);

何度もforしていたのは何だったのか。。  

3. times, each

10.times do
  puts 'hoge!'
end

["h", "o", "g", "e", "!"].each do |val|
  puts val
end
_(10).times(function (index) {
  console.log("hoge");
});

_.each(["h", "o", "g", "e", "!"], function (val) {
  console.log(val);
});

説明不要なほどシンプルです。  

4. uniq, compact

# uniq
[1, 2, 3, 4, 4, 3].uniq
=> [1, 2, 3, 4]

# delete blank? values
[nil, false, 1, 2, 3, 4, 0, ''] - [0, false, nil, '']
=> [1, 2, 3, 4]
// uniq
_.uniq([1, 2, 3, 4, 4, 3])
=> [1, 2, 3, 4]

// delete blank? values
_.compact([null, false, 1, 2, 3, 4, 0, '', undefined])
=> [1, 2, 3, 4]

※ Rubyのcompactでは、nilしか取り除かれないのに対しUnderscore.jsのcompactは、null, false, 0, '', undefined を取除くのでご注意ください。  

5. after

最後に、ご紹介するのはafter。 昨今のJavaScript事情において、非同期処理をさくっとかきたいケースに出会うことが多くなってきました。かといってasync.js等をいれるほどガッツリ書きたいわけでもない、といった時にぜひお使いください。

var books = [
  "リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック",
  "リファクタリング:Rubyエディション",
  "Vimテクニックバイブル ~作業効率をカイゼンする150の技"
];

var read = function (book, callback) {
  console.log(new Date().toLocaleString() + "【" + book + "】を読み始めます");

  setTimeout(function () {
    console.log(new Date().toLocaleString() + "【" + book + "】を読み終わりました!");
    callback(book);
  }, book.length * 100);
}

var finishedReading = _.after(books.length, function () {
  console.log(new Date().toLocaleString() + ' 全ての本を読み終わりました!');
});

_.each(books, function (book) {
  read(book, finishedReading);
});

実行結果

2015/1/28 12:41:52【リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック】を読み始めます
2015/1/28 12:41:52【リファクタリング:Rubyエディション】を読み始めます
2015/1/28 12:41:52【Vimテクニックバイブル ~作業効率をカイゼンする150の技】を読み始めます
...
2015/1/28 12:41:54【リファクタリング:Rubyエディション】を読み終わりました!
2015/1/28 12:41:55【Vimテクニックバイブル ~作業効率をカイゼンする150の技】を読み終わりました!
2015/1/28 12:41:56【リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック】を読み終わりました!
2015/1/28 12:41:56 全ての本を読み終わりました!

3冊目の本を読み終わったタイミングでfinishedReadingメソッドが呼ばれることがわかります。


 

最後に

いかがでしたでしょうか。

Backbone.jsの黒子としてのイメージが強いUnderscore.jsですが、単体で使うことも可能ですので、これを気にちょっとしたJavaScriptを書く際にお使いいただけると幸いです。

マネーフォワードでは、Railsエンジニア/フロントエンドエンジニアを大募集しています! みなさまのご応募お待ちしております!

マネーフォワード採用サイト https://recruit.moneyforward.com/

Wantedly https://www.wantedly.com/companies/moneyforward