【问题标题】:underscorejs pluck two dimensional arrayunderscorejs 抽取二维数组
【发布时间】:2014-04-19 04:25:23
【问题描述】:

第一次使用下划线,我卡住了,找不到例子。

我的数据是:

[{
        "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 为特许经营商 ID 设置值?这两个字段之间存在 1:1 的关系,因此即使获得“第一次找到”的特许经营商 ID 也可以。谢谢!

【问题讨论】:

    标签: javascript arrays underscore.js pluck


    【解决方案1】:

    您可以执行以下操作以按所需顺序获取您的 id/name 对:

    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 中的数组数组,您可以旋转这些数组来构建您的&lt;option&gt;s; stores 将如下所示:

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

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

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

    【讨论】:

      【解决方案2】:

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

      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/

      【讨论】:

      • 这是一种巧妙的方法,可能比 reduce 双重职责更清晰。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-31
      • 2021-03-02
      • 1970-01-01
      • 2016-08-26
      相关资源
      最近更新 更多