【问题标题】:How to convert array of model objects to object with model ids as keys?如何将模型对象数组转换为以模型 ID 作为键的对象?
【发布时间】:2017-03-02 11:39:23
【问题描述】:

在 Javascript 中,我有一个模型对象数组:

[  
   {  
      "id":13,
      "title":"Some title 1",
      "time": "friday"
      ...
   },
   {  
      "id":15,
      "title":"Some title 3",
      "time": "Saturday"
      ...
   },
   {  
      "id":16,
      ...
   },
   ...
]

(每个对象有超过 2 个值和属性) 我想从数组中获取每个 id 的对象移到键,如下所示:

{
  13: {
    title: "Some title 1",
    time: "Friday"
    ...
  },
  15: {
    title: "Some title 3",
    time: "Saturday"
    ...
  },
  16: {
    ...
  },
  ...
}

我正在使用 Rails 视图 .to_json include: {} 语法生成数组,因此 rails 中的答案也对我有用。我将使用带有 Redux 的结果对象作为初始状态,因此某种 Redux 答案也很棒。也会对 es6 和 es5 答案感兴趣(我会使用 es5 答案,因为 Rails 不会在视图中编译 es6,但稍后我们将移植到它也适用的客户端应用程序)。

【问题讨论】:

    标签: javascript ruby-on-rails ecmascript-6 redux map-function


    【解决方案1】:

    最简单的解决方案是遍历数组并将每个项目的副本附加到新对象:

    let result = {};
    for (let item of data) {
      let newObject = Object.assign({}, item);
      result[newObject.id] = newObject;
      delete newObject.id;
    }
    

    如果您以后不需要数据数组,它会变得更加简单:

    let result = {};
    for (let item of data) {
      result[item.id] = item;
      delete item.id;
    }
    

    【讨论】:

    • 我很想知道投票否决可行解决方案的原因。
    • @Aurimas 感谢您的赞赏。
    • 将它作为一个函数会很好,所以我可以说new_items = convert(items)
    【解决方案2】:

    一种简单的方法是在 Ruby 中遍历数组:

    foo = [  
       {  
          "id":13,
          "title":"Some title 1",
          ...
       },
       {  
          "id":15,
          "title":"Some title 3",
          ...
       }]
    
    result = {}
    foo.each {|f| result[f.delete('id')] = f}
    

    【讨论】:

      【解决方案3】:

      您可以使用reduce() 来创建对象,并且可以在内部使用Object.keys()forEach() 循环来循环对象属性以创建内部对象。

      var data = [{
        "id": 13,
        "title": "Some title 1",
        'lorem': 'ipsum'
      }, {
        "id": 15,
        "title": "Some title 3",
      }, {
        "id": 16,
      }]
      
      var result = data.reduce(function(r, e) {
        r[e.id] = {}
        Object.keys(e).forEach(function(k) {
          if(k != 'id') r[e.id] = Object.assign(r[e.id], {[k]: e[k]})
        })
        return r
      }, {})
      
      console.log(result)

      另一种方法是使用reduce() 两次。第一个创建一个外部对象,内部减少在第一个对象中创建每个对象。

      var data = [{"id":13,"title":"Some title 1","lorem":"ipsum"},{"id":15,"title":"Some title 3"},{"id":16}]
      
      var result = data.reduce(function(r, e) {
        r[e.id] = Object.keys(e).reduce(function(o, a) {
         if(a != 'id') o[a] = e[a]
          return o;
        }, {})
        return r;
      }, {})
      
      console.log(result)

      【讨论】:

      • 谢谢,试试看!
      • @Aurimas 请查看更新。您需要从 foreach 循环中创建对象。
      【解决方案4】:

      使用下面的代码

      try {
                  JSONArray jsonArray=new JSONArray("yourJsonString");
                  for(int i=0;i<jsonArray.length();i++){
      
      
                      JSONObject outer_jsonObject=new JSONObject();
                      JSONObject inner_jsonObject=new JSONObject();
      
                      inner_jsonObject.put("title",jsonArray.getJSONObject(i).getString("title"));
                      outer_jsonObject.put(jsonArray.getJSONObject(i).getString("id"),inner_jsonObject);
      
                  }
              } catch (JSONException e) {
                  e.printStackTrace();
              }
      

      【讨论】:

      • 谢谢,很抱歉造成混淆,我没有写这是 Javascript 问题。已更新。
      【解决方案5】:

      我建议您采用以下方法。

      对于每个id,分配一个带有titles 键的对象,并将标题数组作为其值。

      它看起来很干净并且易于阅读,尤其是当id 的标题很少时。

      var arr=[{id:13,title:"Some title 1"},{id:15,title1:"Some title 3",title2:"Some title 4"},{id:16}],     result = [];
      
      arr.forEach(function(v){
        var obj = {};
        var titles = {};
        var titlesArr = [];
        Object.keys(v).forEach(function(c){
          if (c != 'id') {
            titlesArr.push(v[c]);
            titles.titles = titlesArr;
          }
        });
        obj.id = titles;
        result.push(obj);
      });
      
      console.log(result);

      【讨论】:

      • 谢谢。有点让我大吃一惊,不得不考虑这种物体的可能用途。您是否只考虑存在idtitle 属性?我的问题代码中的三个点表示还有更多..
      • @Aurimas 是的,因为这些点,我也这么认为。这就是我为您制定此解决方案的原因。你想让我描述一下每一步吗?
      • 例如,如果我想将这些(子)对象之一渲染为模态,这种结构有什么帮助?说到这里的 Redux/Reat 堆栈
      • @Aurimas 不幸的是,我不在 Redux/React 中,但这个解决方案更整洁,因为您可以在标题数组中存储任意数量的标题。无需使用标题值制作 x 键。这只是我的意见,喜欢的可以使用。
      【解决方案6】:
      return users.reduce((results, u)=> (results[u.id] = u, results), {})
      

      【讨论】:

      • 虽然此代码可能会为问题提供解决方案,但最好添加有关其工作原理/方式的上下文。这可以帮助未来的用户学习并将这些知识应用到他们自己的代码中。在解释代码时,您也可能会以赞成票的形式从用户那里获得积极的反馈。
      猜你喜欢
      • 1970-01-01
      • 2017-03-18
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 2013-03-27
      • 2013-03-25
      • 2017-02-22
      • 2019-07-20
      相关资源
      最近更新 更多