Элегантный, краткий способ переформатировать данные JSON в Javascript? - PullRequest
0 голосов
/ 04 февраля 2019

Я получаю сообщение о результате 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 элементов в каждом разделе, будет даже лучше, если данные превысят десять элементов или сократятся до трех (из-за отсутствия или сокращения данных).

Я думаю о чем-то похожем на использование .forEach (), но по общему признанию мои навыки манипулирования JSON / Object довольно слабые, поэтому я обращаюсь к сообществу в надежде, что кто-то может указать мне вправильное направление или знает о крутой, жесткой рутине / функции, которая достигает того, что я ищу.Заранее благодарим за любые идеи.

Ответы [ 4 ]

0 голосов
/ 05 февраля 2019

Теперь я вижу, что мой ответ в основном такой же, как у Нины, раньше я не видел шаблонов, так что это было круто, но, видя это, я в первый раз, когда я пытался ответить на что-то здесь, я просто поделюсь им в любом случае.

Как 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);
0 голосов
/ 04 февраля 2019

Попробуйте это, используя 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: '' } и т. Д.

0 голосов
/ 04 февраля 2019

Это решение отличается гибкостью от решения от Nina Sholz.Нина позволяет вам подобрать любой стиль, содержащий номер ключа.Но для этого также необходимо добавить шаблон.Моя будет обрабатывать любые ключи, которые содержат только одну последовательность цифр, но ничего более сложного.Но вам не нужно ничего делать для обработки таких шаблонов.

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))

Я понятия не имею, нужна ли вам какая-либо гибкость, но это интересные альтернативы друг другу.

0 голосов
/ 04 февраля 2019

Вы можете взять массив искомых ключей с заполнителем для рабочего числа и построить новый объект и отправить их в набор результатов.

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; }

С литералами шаблона

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; }
...