【问题标题】:How to create hashmap from object by manipulating specific keys如何通过操作特定键从对象创建 hashmap
【发布时间】:2018-05-14 03:46:48
【问题描述】:

尝试了几天来操纵一些 JSON 数据响应。如何从以下创建哈希图?

var jsonObject = JSON.parse(xhr.responseText); //response that parced

用于搜索"volvo, opel, honda。解析后,它会返回每个索引的用户,看起来像这样(jsonObject.length 在每个不同的搜索中都会发生变化):

[{user: 1, car: volvo, score:7, time: "some time"},{user: 2, car: volvo, score:8, time: "some time"},{user: 3, car: volvo, score:9, time: "some time"},{user: 3, car: opel, score:6, time: "some time"},{user: 3, car: honda, score:8, time: "some time"},{user: 4, car: volvo, score:6, time: "some time"},{user: 4, car: opel, score:7, time: "some time"},{user: 5, car: honda, score:8, time: "some time"}]

我希望输出是这样的:

[{1:[7]},{2:[8]},{3:[9,6,8]},{4:[6,7]},{5:[8]}]

【问题讨论】:

  • 你的jsonObject的结构是什么?
  • “结构”是什么意思,上面我举了个例子,抱歉没看懂问题

标签: javascript arrays json loops hashmap


【解决方案1】:

您可以减少数组并使用对象收集每个用户的所有分数,以确保您拥有唯一的用户 ID 作为键

const jsonObject = [
  {user: 1, car: 'volvo', score:7, time: "some time"}
, {user: 2, car: 'volvo', score:8, time: "some time"}
, {user: 3, car: 'volvo', score:9, time: "some time"}
, {user: 3, car: 'opel', score:6, time: "some time"}
, {user: 3, car: 'honda', score:8, time: "some time"}
, {user: 4, car: 'volvo', score:6, time: "some time"}
, {user: 4, car: 'opel', score:7, time: "some time"}
, {user: 5, car: 'honda', score:8, time: "some time"} 
]

const results = jsonObject.reduce((map, obj) => {
  // set a new key based on the user id if it doesn't exist
  if (!map.has(obj.user)) {
    map.set(obj.user, [])
  }
  // add to the users scores to the users score
  map.get(obj.user).push(obj.score)
  // return the accumulator
  return map
}, new Map)

for (let [key, value] of results.entries()) {
  console.log({
    key,
    value
  })
}
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>

【讨论】:

  • 非常感谢。但我不能改变结果。如果我将它存储在一个 var(例如 myObject)中,myObject[0] 是未定义的,甚至在每个数组中都没有 mor
  • @Panos 将其放入地图而不是对象中很容易解决,请参阅更新后的代码。
  • 这真的很棒。几天来,我试图将正确的输出成功地转换为地图。在您更新代码之前,我用草率的方式做了我想要的。 JSON.stringify、str.replace 和 JSON.parse 再次使键成为字符串。长度
  • @Panos 很高兴它对你有用。使用数据而不是使用充满问题的字符串的正则表达式要好得多。如果您正在处理大量结果,则可能值得将结果分块或使用工作人员进行处理,这样您就不会阻碍应用程序的其余部分,或者如果这是一个节点应用程序,最好使用 MongoDB 之类的东西.
【解决方案2】:

使用 ES5

Reduce 数组,并使用辅助对象通过用户名设置对创建对象的引用:

var data = [{user: 1, car: 'volvo', score:7, time: "some time"},{user: 2, car: 'volvo', score:8, time: "some time"},{user: 3, car: 'volvo', score:9, time: "some time"},{user: 3, car: 'opel', score:6, time: "some time"},{user: 3, car: 'honda', score:8, time: "some time"},{user: 4, car: 'volvo', score:6, time: "some time"},{user: 4, car: 'opel', score:7, time: "some time"},{user: 5, car: 'honda', score:8, time: "some time"}];

var helper = {};
var result = data.reduce(function(r, o) {    
  if(!helper[o.user]) {
    helper[o.user] = {};
    r.push(helper[o.user]);
    helper[o.user][o.user] = [];
  }
  
  helper[o.user][o.user].push(o.score);
  
  return r;
}, []);

console.log(result);

使用 ES6

Reduce数组变成Map,然后spreadMap的values返回数组:

const data = [{user: 1, car: 'volvo', score:7, time: "some time"},{user: 2, car: 'volvo', score:8, time: "some time"},{user: 3, car: 'volvo', score:9, time: "some time"},{user: 3, car: 'opel', score:6, time: "some time"},{user: 3, car: 'honda', score:8, time: "some time"},{user: 4, car: 'volvo', score:6, time: "some time"},{user: 4, car: 'opel', score:7, time: "some time"},{user: 5, car: 'honda', score:8, time: "some time"}];

const result = [...data.reduce((m, { user, score }) => {  
  const scores = m.get(user) || { [user]: [] };
  
  scores[user].push(score);
  
  return m.set(user, scores);
}, new Map()).values()];

console.log(result);

【讨论】:

    【解决方案3】:

    这是一个普通的旧 JS 方法,没有 map、reduce 或东西

    const data = [{"user":1,"car":"volvo","score":7,"time":"some time"},{"user":2,"car":"volvo","score":8,"time":"some time"},{"user":3,"car":"volvo","score":9,"time":"some time"},{"user":3,"car":"opel","score":6,"time":"some time"},{"user":3,"car":"honda","score":8,"time":"some time"},{"user":4,"car":"volvo","score":6,"time":"some time"},{"user":4,"car":"opel","score":7,"time":"some time"},{"user":5,"car":"honda","score":8,"time":"some time"}];
    
    let res = []
    data.forEach((item) => {
      if (res.length === 0) {
        res.push({[[item.user]]: [item.score]})
      }else {
        let index = -1;
        res.some((obj, i) => {
          if (Number(Object.keys(obj)[0]) === item.user) {
            index = i
            return true;
          }
          return false;
        })
        if (index !== -1) {
          res[index][item.user].push(item.score)
        } else {
          res.push({[item.user]: [item.score]})	
        }
      }
    })
    
    console.log(res)

    【讨论】:

    • 谢谢它成功了,我可以使用 myObject[i].values 获取每个数组的值但是你现在如何获取 myObject[i][key]?具体例子中的1、2等。
    • 有没有什么办法让用户的值成为新对象的键(并且是数字并且不可访问)成为字符串“1”或“user_1”,而不仅仅是1?跨度>
    猜你喜欢
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多