LoginSignup
7
7

More than 5 years have passed since last update.

FuelPHPのArr::get()をJavaScriptで実装して、多階層のオブジェクトの値を簡単に取得する

Last updated at Posted at 2014-07-17

続・多階層のオブジェクトのアクセスへの挑戦

階層が深くなったJavaScriptオブジェクトのプロパティが定義されているかどうか判定するに続いて、紆余曲折ありまして、FuelPHPのArr::get()をJavaScriptで実装してみることにしました。FuelPHPのArrクラスには色々と便利なメソッドがあり、JavaScriptにも応用できそうなものがあったりするので今後も何か変換してみようかなとか思っていたりします。使うかどうか不明ですが...。

ソース

fuel.js
/**
 * @fileoverview FuelPHPのcoreクラスをJS化して使えるようにするためのクラス群
 * 作成した時点でのFuelPHPのバージョンは 1.7.1
 */
var FuelJS = FuelJS || {};
FuelJS.core = FuelJS.core || {};

/** 
 * \Fuelクラス(の一部)
 *
 * @constructor 
 */
FuelJS.core.Fuel = (function () {
    return {
        /**
         * Takes a value and checks if it is a Closure or not, if it is it
         * will return the result of the closure, if not, it will simply return the
         * value.
         *
         * @param   {*}       value
         * @return  {*}
         */
        value : function (value) {
            return typeof value === 'function' ? value() : value;
        }
    };
}());

/** 
 * \Arrクラス(の一部)
 *
 * @constructor 
 */
FuelJS.core.Arr = (function () {

    var _private = {
        isArray : function (value) {
            return (Array.isArray ?
                Array.isArray(value)
                : Object.prototype.toString.call(value) === '[object Array]') ||
                    Object.prototype.toString.call(value) === '[object Object]';
        }
    };

    var _this = {
        /**
         * Gets a dot-notated key from an array, with a default value if it does
         * not exist.
         *
         * @param   {!Object|Array}          array          The search array
         * @param   {string|Array}           key            The dot-notated key or array of keys
         * @param   {*}                      defaultVal     The default value
         * @return  {*}
         */
        get : function (array, key, defaultVal) {
            if ( ! _private.isArray(array)) {
                throw new TypeError('First parameter must be an array or ArrayAccess object.');
            }

            if (typeof key === 'undefined' || key === null) {
                return array;
            }

            if (_private.isArray(key)) {
                var ret = {};
                for (var i = 0, len = key.length; i < len; i++) {
                    ret[key[i]] = self.get(array, key[i], defaultVal);
                }
                return ret;
            }

            if (array.hasOwnProperty(key)) {
                return array[key];
            }

            for (var i = 0, keys = (key).toString().split('.'), len = keys.length; i < len; i++) {
                if ((_private.isArray(array) && typeof array[keys[i]] !== 'undefined') === false) {
                    if ( ! _private.isArray(array) || ! array.hasOwnProperty(keys[i])) {
                        return FuelJS.core.Fuel.value(defaultVal || null);
                    }
                }

                array = array[keys[i]];
            }

            return array;
        },
    };

    var self = _this;

    return self;
}());

動作確認

sample

// Alias
var log = function (arg) { console.log(arg); };

var array = [9, 8, 7, {a: {b: {c : {d : {}}}}}];


log(FuelJS.core.Arr.get(array));                       // [9, 8, 7, {a: {b: {c : {d : {}}}}}]
log(FuelJS.core.Arr.get(array, null));                 // [9, 8, 7, {a: {b: {c : {d : {}}}}}]
log(FuelJS.core.Arr.get(array, ['0', '2', '5']));      // {0: 9, 2: 7, 5: null}
log(FuelJS.core.Arr.get(array, '0'));                  // 9
log(FuelJS.core.Arr.get(array, '1'));                  // 8
log(FuelJS.core.Arr.get(array, '2'));                  // 7
log(FuelJS.core.Arr.get(array, '4'));                  // null
log(FuelJS.core.Arr.get(array, '4', 'defaultValue!')); // defaultValue!
log(FuelJS.core.Arr.get(array, '3'));                  // {a: {b: {c : {d : {}}}}}
log(FuelJS.core.Arr.get(array, '3.a'));                // {b: {c : {d : {}}}}
log(FuelJS.core.Arr.get(array, '3.a.b'));              // {c : {d : {}}}
log(FuelJS.core.Arr.get(array, '3.a.b.c'));            // {d : {}}
log(FuelJS.core.Arr.get(array, '3.a.b.c.d'));          // {}
log(FuelJS.core.Arr.get(array, '3.a.b.c.d.e'));        // null

軽く説明とか

  1. FuelJS.core.Fuel のクラスを用意したのはデフォルト値の扱いをFuelに近づけておきたかったからです。 \Arr::get() は該当する要素がなかった場合の対応として第三引数にデフォルト値を設定できます。これには関数を渡すことも可能で、要素がなければ渡した関数の実行結果が返ります。

  2. FuelJS.core.Arr_private.isArray は配列とオブジェクトを許容します。
    JavaScript標準の Array.isArray を使用してしまうと、せっかくのメソッドでObjectが使用できなくなってしまうので拡張しています。

言い訳

  1. JavaScriptの名前空間とかほぼわかっていません。この辺は無視していただけると...。
  2. 突貫工事で作成したのでちゃんとテストしてませんごめんなさい(スライディング土下座

参考(リファレンスなど)

Arr - クラス - FuelPHP ドキュメント

7
7
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
7
7