underscorejs采用二维数组

时间:2014-04-19 04:25:24

标签: javascript arrays underscore.js pluck

第一次使用下划线而我被困住了,找不到一个例子。

我的数据是:

[{
        "store_name": "Store 1",
        "franchisee_id": "id01",
        "dish_menu": "Breakfast",
        "dish_count": "17"
    }, {
        "store_name": "Store 1",
        "franchisee_id": "id01",
        "dish_menu": "Light Meals",
        "dish_count": "7"
    }, {
        "store_name": "Store 1",
        "franchisee_id": "id01",
        "dish_menu": "Sandwiches",
        "dish_count": "12"
    }, {
        "store_name": "Store 2",
        "franchisee_id": "id02",
        "dish_menu": "Breakfast",
        "dish_count": "7"
    },
        ............
]

我已经管理(在这里有一些帮助)使用以下链式命令拉出不同的store_name,然后将其放入我正在构建的HTML语句中:

var stores = _.chain(json).pluck("store_name").sort().uniq(true).value();
var tempHTML = "";

stores.forEach(function (entry) {
    tempHTML = tempHTML + '<option value="' + entry + '">' + entry + '</option>';
});

但我尝试将franchisee_id与不同的store_name相匹配,并基本上构建我的HTML,如下所示:

stores.forEach(function (entry) {
    tempHTML = tempHTML + '<option value="' + FRANCHISEE_ID + '">' + STORE_NAME + '</option>';
});

使用store_name值有没有办法_.pluck franchisee_id的值?这两个字段之间存在1:1的关系,所以即使获得“首次发现”特许经营权也很好。谢谢!

2 个答案:

答案 0 :(得分:3)

您可以执行以下操作,以便按所需顺序获取您的ID /名称对:

var map_id_to_name = function(m, o) {
    m[o.franchisee_id] = o.store_name;
    return m;
};
var arrayify = function(name, id) {
    return [ name, id ];
};
var stores = _(data).chain()
                    .reduce(map_id_to_name, { })
                    .map(arrayify)
                    .sortBy(_.first)
                    .value();

演示:http://jsfiddle.net/ambiguous/9xxS6/

这将为您提供stores中的一系列数组,您可以通过这些数组来构建<option> s; stores将如下所示:

[
    [ "Store 1", "id01" ],
    [ "Store 2", "id02" ],
    ...
]

商店名称将位于内部数组的第一个条目中,而特许经营权ID将位于第二个条目中。整个事情将按商店名称排序。如果您想要不区分大小写的排序,则可以.sortBy(function(a) { return a[0].toLowerCase() })代替。

reduce(map_id_to_name, { })使用Object收集唯一的id / name对,以自动强制唯一性(对象中的键毕竟是唯一的)。然后map(arrayify)将Object转换为数组数组,以便您可以对事物进行排序。您可以使用对象数组,这只是对mapsortBy调用的一个小改动。

答案 1 :(得分:1)

另一种方法,从对象中提取所需信息,然后过滤生成的数组以获取唯一对象:

var stores = _(data).chain()

// convert each object to {store_name: ..., franchisee_id: ...}
.map(function(m) {
    return _.pick(m, "store_name", "franchisee_id");
})

//keep one of each
//can be shortened to .uniq(_.property('franchisee_id'))
.uniq(function(m) {
    return m.franchisee_id;
})

//sort by name
.sortBy("store_name")

//and get the array
.value();

你的最终数组看起来像

[
    {store_name: "Store 1", franchisee_id: "id01"},
    {store_name: "Store 2", franchisee_id: "id02"}
]

使用http://jsfiddle.net/mr82s/

进行演示

有了一点_.mixin魔法,你可以进一步将它压缩到

_.mixin({
    properties: function() {
        var args = _.toArray(arguments);
        return function(obj) {
            return _.pick(obj, args);
        };
    }
});

var stores = _(data).chain()
.map(_.properties("store_name", "franchisee_id"))
.uniq(_.property('franchisee_id'))
.sortBy("store_name")
.value()

http://jsfiddle.net/nikoshr/mr82s/1/