用Java格式重新格式化JSON数据的优雅简洁方法?

时间:2019-02-04 15:20:31

标签: javascript json javascript-objects reformatting

我从旧的数据库查询中收到以下格式的JSON结果消息,该消息我目前无法更改:

{
  "vsm1": "2429",
  "vsm2": "2488",
  "vsm3": "1968",
  "vsm4": "",
  "vsm5": "",
  "vsm6": "",
  "vsm7": "",
  "vsm8": "",
  "vsm9": "",
  "vsm10": "",
  "color1": "5",
  "color2": "4",
  "color3": "4",
  "color4": "0",
  "color5": "0",
  "color6": "0",
  "color7": "0",
  "color8": "0",
  "color9": "0", 
  "color10": "0",
  "p1mtime": "1549296004",
  "p2mtime": "1549296009",
  "p3mtime": "1549296014",
  "p4mtime": "",
  "p5mtime": "",
  "p6mtime": "",
  "p7mtime": "",
  "p8mtime": "",
  "p9mtime": "",
  "p10mtime": "",
  "inch1": "",
  "inch2": "",
  "inch3": "",
  "inch4": "",
  "inch5": "",
  "inch6": "",
  "inch7": "",
  "inch8": "",
  "inch9": "",
  "inch10": "" 

}

我想将其重新格式化为更有用的对象,如下所示:

{ id: 1, vsm: 2429, color: 5, pmtime: 1549296004, inch: 0  }
{ id: 2, vsm: 2488, color: 4, pmtime: 1549296009, inch: 0  }
{ id: 3, vsm: 1968, color: 4, pmtime: 1549296014, inch: 0  }

...等等。

当前,传入数据仅限于每个“节”中的十个(vsm1,vsm2,... vsm10,color1,color2,... color10等),因此在这十个元素上存在某种静态循环在每个部分中,我都是从这里开始的,但是看起来很丑,而且肯定不灵活。

一个聪明的代码段可以处理每个部分中的n个元素,以防万一数据超过10个元素或下降到3个(由于缺少数据或修剪的数据)。

我正在考虑使用.forEach()的方法,但是我承认我的JSON /对象操作技能很差,所以我转向社区,希望有人可以向我指出正确的方向或知道可以实现我想要的功能的紧凑,紧凑的例程/功能。预先感谢您的任何见解。

4 个答案:

答案 0 :(得分:6)

您可以使用所需键的数组作为占位符来表示运行编号,然后构建新对象并将其推入结果集中。

var data = { vsm1: "2429", vsm2: "2488", vsm3: "1968", vsm4: "", vsm5: "", vsm6: "", vsm7: "", vsm8: "", vsm9: "", vsm10: "", color1: "5", color2: "4", color3: "4", color4: "0", color5: "0", color6: "0", color7: "0", color8: "0", color9: "0", color10: "0", p1mtime: "1549296004", p2mtime: "1549296009", p3mtime: "1549296014", p4mtime: "", p5mtime: "", p6mtime: "", p7mtime: "", p8mtime: "", p9mtime: "", p10mtime: "", inch1: "", inch2: "", inch3: "", inch4: "", inch5: "", inch6: "", inch7: "", inch8: "", inch9: "", inch10: "" },
    keys = ['vsm*', 'color*', 'p*mtime', 'inch*'],
    result = [],
    id = 1;

while (keys[0].replace('*', id) in data) {
    result.push(Object.assign(
        { id },
        ...keys.map(k => ({ [k.replace('*', '')]: +data[k.replace('*', id)]  || 0 }))
    ));
    id++;
}

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

使用template literals

var data = { vsm1: "2429", vsm2: "2488", vsm3: "1968", vsm4: "", vsm5: "", vsm6: "", vsm7: "", vsm8: "", vsm9: "", vsm10: "", color1: "5", color2: "4", color3: "4", color4: "0", color5: "0", color6: "0", color7: "0", color8: "0", color9: "0", color10: "0", p1mtime: "1549296004", p2mtime: "1549296009", p3mtime: "1549296014", p4mtime: "", p5mtime: "", p6mtime: "", p7mtime: "", p8mtime: "", p9mtime: "", p10mtime: "", inch1: "", inch2: "", inch3: "", inch4: "", inch5: "", inch6: "", inch7: "", inch8: "", inch9: "", inch10: "" },
    templates = [id => `vsm${id}`, id => `color${id}`, id => `p${id}mtime`, id => `inch${id}`],
    result = [],
    id = 1;

while (templates[0](id) in data) {
    result.push(Object.assign(
        { id },
        ...templates.map(t => ({ [t('')]: +data[t(id)]  || 0 }))
    ));
    id++;
}

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:2)

尝试此操作,使用oldObject您要清除的对象:

var cleanedObject = {};
for (let [key, value] of Object.entries(oldObject)) {
  let index = key.match('[0-9]+');
  cleanedObject[index] = cleanedObject[index] || {};
  cleanedObject[index][key.replace(index, '')] = value;
}

结果将是cleanedObject['1'] = { vsm: 2429, color: 5, pmtime: 1549296004, inch: '' }所在的对象,依此类推。

答案 2 :(得分:1)

此解决方案与Nina Sholz的解决方案具有不同的灵活性。 Nina允许您匹配任何样式的包含数字的键。但这还需要您添加模板才能这样做。我的将处理任何只包含单个数字但没有更复杂的键。但这不需要您做任何事情来处理此类模板。

const reformat = data => Object.values(Object.keys(data)
  .reduce(
    (a, k, i, _, d = k.match(/\d+/)[0])  => ({
      ...a, 
      [d]: {...(a[d] || {id: Number(d)}), [k.replace(/\d+/, '')]: data[k]}
    }), {})).sort((a, b) => a.id - b.id)

const data = {"vsm1":"2429","vsm2":"2488","vsm3":"1968","vsm4":"","vsm5":"","vsm6":"","vsm7":"","vsm8":"","vsm9":"","vsm10":"","color1":"5","color2":"4","color3":"4","color4":"0","color5":"0","color6":"0","color7":"0","color8":"0","color9":"0","color10":"0","p1mtime":"1549296004","p2mtime":"1549296009","p3mtime":"1549296014","p4mtime":"","p5mtime":"","p6mtime":"","p7mtime":"","p8mtime":"","p9mtime":"","p10mtime":"","inch1":"","inch2":"","inch3":"","inch4":"","inch5":"","inch6":"","inch7":"","inch8":"","inch9":"","inch10":""}

console.log(reformat(data))

我不知道您是否需要任何一种灵活性,但是这些是彼此之间很有趣的选择。

答案 3 :(得分:1)

我现在看到我的答案与Ninas基本相同,以前没有看过模板,所以很酷,但是因为这是我第一次尝试在此处回答问题,我还是会分享它

作为Ninas,这可以处理任何长度的数据。

const data = {"vsm1": "2429",
  "vsm2": "2488",
  "vsm3": "1968",
  "vsm4": "",
  "color1": "5",
  "color2": "4",
  "color3": "4",
  "color4": "0",
  "p1mtime": "1549296004",
  "p2mtime": "1549296009",
  "p3mtime": "1549296014",
  "p4mtime": "",
  "inch1": "",
  "inch2": "",
  "inch3": "",
  "inch4": "",
  };


const vsmRegex = new RegExp("(vsm\\d)");
const keys = Object.keys(data);

const result = [];
let id= 1;

for(let i = 0; i < keys.length; i++) {
  if(keys[i].match(vsmRegex)) {
    let object = {
      id: id,
      vsm: Number(data[`vsm${id}`]) || 0,
      color: Number(data[`color${id}`]) || 0,
      pmtime: Number(data[`p${id}mtime`]) || 0,
      inch: Number(data[`inch${id}`]) || 0
    };
    result.push(object);
    id++;
  } else {
    break;
  }
}

console.log(result);