2

私は jQuery とunderscore.jstitle1-2を使用していますが、アクションを対応させたいと思っています。

this.items = {
    menuItems: [
        { title: 'title1',
            data: [
                { title: 'title1-1',
                    action: 'action1-1'
                },
                { title: 'title1-2',
                    action: 'action1-2'
                }
                ]
        },
        { title: 'title2',
            data: [
                { title: 'title2-1',
                    action: 'action2-1'
                },
                { title: 'title2-2',
                    action: 'action2-2'
                }
            ]
        }
    ]
};

現在、これを行うには次のコードがあります。

var item = _.find(_.flatten(_.pluck(this.items.menuItems, 'data')), function (item) { return item.title === 'title1-2'; });
console.log(item.action);

それを見つけるより良い方法はありますか?

4

2 に答える 2

2

に切り替える_.chainと、少し理解しやすくなります。

var item = _.chain(items.menuItems)
            .pluck('data')
            .flatten()
            .find(function(i) { return i.title === 'title1-2' })
            .value();

デモ: http://jsfiddle.net/ambiguous/mPa3m/

a の中で aを使用してpluckandをスキップすることもできます。flattenfindmap

var right_title = function(i) { return i.title === 'title1-2' };
var is_there    = function(i) { return i };
var item        = _.chain(items.menuItems)
                   .map(function(i) { return _(i.data).find(right_title) })
                   .find(is_there)
                   .value();

デモ: http://jsfiddle.net/ambiguous/uRBuZ/

または、昔ながらの方法で、ショートサーキットのネストされたループを使用します。

var i, j, sub, item;
for(i = 0, item = null; !item && i < items.menuItems.length; ++i)
    for(j = 0, sub = items.menuItems[i]; !item && j < sub.data.length; ++j)
        if(sub.data[j].title === 'title2-1')
            item = sub.data[j];

デモ: http://jsfiddle.net/ambiguous/7xt5D/

これはいくつかの参照をコピーするだけなので、記憶に残りやすく、最初の可能な機会で停止するため、適切に怠け者でもあります。

これを頻繁に行う場合は、タイトルで直接アクセスできるようにインデックスを作成するのが理にかなっています。

var idx = { };
var i, j, sub, item;
for(i = 0, item = null; !item && i < items.menuItems.length; ++i)
    for(j = 0, sub = items.menuItems[i]; !item && j < sub.data.length; ++j)
        idx[sub.data[j].title] = sub.data[j];
console.log(idx['title1-2']);

デモ: http://jsfiddle.net/ambiguous/SJuHp/

上記は、タイトルが一意であることを前提としていますが、idxそれが問題である場合は、配列に簡単に切り替えることができます。this.itemsinへの変更も追跡する必要がありますがidx、すべてをオブジェクト内に隠し、そのオブジェクトのメソッドのみを使用してデータを処理する場合は簡単です。

于 2012-05-23T15:50:09.130 に答える
0

巧妙なアプローチですが、オブジェクトのサイズが大きくなるにつれて最も効率的ではありません (サブ配列の複数の操作)。2 つの underscore.js 検索を行う方がよいと思います。最初は titlex に一致するmenuitemに対して、次にtitlex-y に一致するデータに対してです。

var item = _.find(
    _.find(
        this.items.menuItems, function(item) {
            return item.title === 'title1'
        }).data,
    function(item) {
        return item.title = 'title1-2'
    });
于 2012-05-23T15:32:26.187 に答える