40歳からのキャリアチェンジ

20代はエンジニア・PM、30代はWeb系エンジニア向けのキャリアアドバイザー。40代の今はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連あたり

underscore.jsの力を借りてJSON形式のデータ並べ替えを行う

Titanium Nagoya Chatroom と同じ日に東京で行われていたAndroid Bazaar and Conference 2012 でScaling Titanium Mobileというお話をqnypの@junyaさんがされていました。

Titanium Nagoya Chatroomで喋り終えた後の帰りの新幹線で上記スライドのPDF版ダウンロードして読んでいてunderscore.jsの特徴について

  • 配列や関数に対する操作を容易にする
  • JavaScriptのビルトインオブジェクトを拡張しない
  • 関数プログラミング由来のものを中心とした60ほどの関数

ということが書かれており最後の関数プログラミング由来・・という部分にちょっと興味惹かれました。

自分は以前にWSH+JScript+prototype.jsで業務効率化のツール(詳しくはこれ)をちょこちょこ作っていたこともあり、underscore.jsのeach、map、invoke、pluck・・というあたりはprototype.js のそれと通じるので使うのに心理的に敷居が低く感じられました。

どんな状況で使おうとしているか?

今こんなアプリを作ってます。
f:id:h5y1m141:20120329073317p:plain

MongoDBのクラウドサービスのmongolabに格納してあるブログのエントリ情報を取得する際にJSONDBに元々備わっているmongolab連携機能を活用してます。

取得自体は問題なく出来ているのですが、ブログの更新日付順にソートした状態にしたいのに、それが機能せずに悩んでいたのでunderscore.jsに助けてもらおうと思って使うことにしました

underscore.js使うための準備

underscore.jsのサイトからダウンロードします

f:id:h5y1m141:20120329075613p:plain

ダウンロードしたファイルを自分が作ってるプロジェクトのResources配下の任意の場所に配置します。
※自分の場合には他の方が作った便利ライブラリはlib/以下に配置するようにしているためこのような感じになります。

f:id:h5y1m141:20120329075638p:plain

使い方

  var _ = require('lib/underscore')._;
  var origin = [
    {
      post_date:"2006/01/01 00:00:00",
      title:'Abb更新が止まっている',
      id:3
    },
    {
      post_date:"2005/12/01 12:00:01",
      title:'Google',
      id:1
    },
    {
      post_date:"2006/04/01 13:00:04",
      title:'Aaa-はじめまして',
      id:2
    }
  ];

  var data = _.chain(origin)
      .sortBy(function(item) {return item.post_date; })
      .value();
  Ti.API.info(data);

上記の例だと、post_dateをキーにして並べ替えが実行されるのでTi.API.infoの結果は以下のようになります。

[INFO] (
{
id = 1;
"post_date" = "2005/12/01 12:00:01";
title = Google;
},
{
id = 3;
"post_date" = "2006/01/01 00:00:00";
title = "Abb\U66f4\U65b0\U304c\U6b62\U307e\U3063\U3066\U3044\U308b";
},
{
id = 2;
"post_date" = "2006/04/01 13:00:04";
title = "Aaa-\U306f\U3058\U3081\U307e\U3057\U3066";
}
)

もしも、idをキーにソートしたい場合には

  var data = _.chain(origin)
      .sortBy(function(item) {return item.id; })
      .value();

とすればOKです。

並べ替えの順番を反対にしたい場合にはdata.reverse()とすれば意図した結果が得られると思います。

今後に向けて

mongolabから取得したデータはローカルにキャッシュする仕様を考えてて、そこの処理はJSONDBモジュールで簡単に実現出来ているのですが、ローカルから読み込んだJSONデータに対してちょっとフィルタをかけたい場合などに再びローカルキャッシュにクエリーを投げず、underscore.jsの力を借りて読み込む済のJSONデータに対して処理する事ができないかなとちょっと考えています。