Преобразование JSON в массив объектов с использованием lodash - PullRequest
2 голосов
/ 19 марта 2019

У меня есть объект JSON в базе данных NoSql в этом формате. Мы получаем эти данные после переноса некоторых записей из другой базы данных, и это многозначные поля (в основном мы пытаемся очистить данные для дальнейшей обработки).

{
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
}

Я хочу добавить еще один ключ "bpTableDataName" в тот же JSON, который должен иметь этот формат и значения,

"bpTableDataName": [
    {
      "name": "aName",
      "email": "aEmail",
      "pwdid": "aPWID"
    },
    {
      "name": "bName",
      "email": "bEmail",
      "pwdid": "bPWID"
    },
    {
      "name": "cName",
      "email": "cEmail",
      "pwdid": "cPWID"
    }
  ],

Есть ли способ, которым мы можем достичь этого, используя lodash?

Ответы [ 6 ]

1 голос
/ 19 марта 2019

Попробуйте следующий код -

o = {
  "BPContName": "aName;bName;cName",
  "BPContEmail": "aEmail;bEmail;cEmail",
  "BPContPWID": "aPWID;bPWID;cPWID"
}

map = { "BPContName" : "name", "BPContEmail": "email", "BPContPWID": "pwdid" }

const result = _.reduce(o, (arr, v, k) => ( v.split(";").forEach((x,i) => _.set(arr, `${i}.${map[k]}`, x)), arr ), [])
   
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
0 голосов
/ 19 марта 2019

В основном вам нужно zip это.

Отрывок:

let obj = {"BPContName":"aName;bName;cName","BPContEmail":"aEmail;bEmail;cEmail","BPContPWID":"aPWID;bPWID;cPWID"},
    res = _.zipWith(
      ..._.map(obj, v => v.split(';')),
      (name, email, pwid) => ({name, email, pwid})
    );
    
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Обратите внимание, последовательность параметров, которую мы должны поместить таким образом, исходный объект дает нам значения при использовании Object.values или дает нам ключи при использовании Object.keys обычно это в алфавитном порядке. Но в случае, если в каком-либо env порядке порядок не гарантирован, мы можем отсортировать его по последовательности ключей в качестве метаданных.

Или вы можете явно передать аргументы, например:

(obj.BPContName.split(';'), obj.BPContEmail.split(';'), obj.BPContPWID.split(';'))
0 голосов
/ 19 марта 2019

Вы можете использовать lodash _.flow() для создания функции.Используйте _.map() с _.overArgs(), чтобы создать функцию, которая разделяет значения, отформатирует ключ и затем преобразует их в массив пар, используя _.unzip(), например [['name', 'x'], ['name', 'y']].Перенесите массив массивов с помощью _.unzip(), чтобы объединить пары разных свойств.Затем используйте _.map() для итерации и преобразуйте каждый массив пар в объект, используя _.fromPairs().

const { flow, partialRight: pr, map, unzip, overArgs, times, size, constant, split, fromPairs } = _

const keysMap = new Map([['BPContName', 'name'], ['BPContEmail', 'email'], ['BPContPWID', 'pwdid']])

const formatKey = key => keysMap.get(key)
const splitVals = pr(split, ';')

const fn = flow(
  pr(map, overArgs(
    (vals, k) => unzip([vals, times(size(vals), constant(k))]),
    [splitVals, formatKey])
  ),
  unzip, // transpose
  pr(map, fromPairs) // convert each pairs array to object
)

const data = {
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
}

const results = fn(data)

console.log(results)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
0 голосов
/ 19 марта 2019

Использование Object.assign, Object.entries, Array#map и оператора распространения делают это тривиальным

    const inputdata = {
        "BPContName":"aName;bName;cName",
        "BPContEmail":"aEmail;bEmail;cEmail",
        "BPContPWID":"aPWID;bPWID;cPWID"
    };

    const t1=Object.assign({},...Object.entries(inputdata).map(([k,v])=>({[k]:v.split(';')})));
    inputdata.bpTableDataName=t1.BPContName.map((name,i)=>({name,email:t1.BPContEmail[i],pwdid:t1.BPContPWID[i]}));
    console.log(inputdata);

Конечно, это не был бы я без однострочного

const obj = {
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
};
// one line to rule them all
obj.bpTableDataName=Object.entries(obj).reduce((r,[k,v])=>(v.split(';').forEach((v,i)=>(r[i]=r[i]||{})[{BPContName:'name',BPContEmail:'email',BPContPWID:'pwdid'}[k]]=v),r),[]);
//
console.log(obj);
0 голосов
/ 19 марта 2019

Вы можете reduce записи, возвращаемые Object.entries, например:

let obj = {
  "BPContName": "aName;bName;cName",
  "BPContEmail": "aEmail;bEmail;cEmail",
  "BPContPWID": "aPWID;bPWID;cPWID"
}

let bpTableDataName = Object.entries(obj).reduce((r, [key, value]) => {
  let splits = value.split(";");
  key = key.replace("BPCont", "").toLowerCase();
  splits.forEach((split, i) => (r[i] = r[i] || {})[key] = split)
  return r;
}, [])

obj.bpTableDataName = bpTableDataName;

console.log(obj)
  • Object.entries возвращает массив пары ключ-значение. Цикл каждого из них
  • split каждое значение в ;
  • получить ключ, удалив BPCont деталь и сделав его lowerCase
  • Перебирать splits и обновлять определенные ключи объектов для каждого индекса

Обновление:

Поскольку у вас есть дополнительный d в ключе вывода, вы можете создать объект отображения:

propertyMap = {
  "BPContName": "name",
  "BPContEmail": "email",
  "BPContPWID": "pwdid"
}

А внутри reduce измените код replace на этот:

key = propertyMap[key]
0 голосов
/ 19 марта 2019

Вы можете использовать split(), чтобы разделить значения в массив.Затем выполните итерацию по массиву и создайте требуемый json, а затем вставьте его в результаты.

Проверьте это.

var data = {
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
}
var names = data.BPContName.split(';');
var emails = data.BPContEmail.split(';');
var pwids = data.BPContPWID.split(';');

var results = [];

for(var i = 0 ; i < names.length; i++) {
  var obj = {
    name: names[i],
    email: emails[i],
    pwdid: pwids[i]
  }
  results.push(obj);
}

console.log(results)
...