#node.js #json #dictionary #indexing
#node.js #json #словарь #индексирование
Вопрос:
Я пытаюсь получить значения в файл JSON на основе сопоставления полей из другого файла JSON. У меня есть файл JSON, который я получаю от внешних систем, у которых разные имена полей. Я создал файл JSON, который сопоставит поля из внешней системы с именами, в которых мне нужны поля:
{
"username":"user",
"externalSystemId":"id",
"active":"active",
"type":"type",
"patronGroup":"group",
"meta": {
"creation_date":"dateCreated",
"last_login_date":"lastLogin"
},
"personal": {
"lastName":"lname",
"firstName":"fname",
"email":"email",
"phone":"phone",
"mobilePhone":"mobile",
"dateOfBirth":"birthDate",
"addresses":{
"countryId": "countryCode",
"addressLine1": "address",
"addressLine2": "address2",
"city": "city",
"region": "region",
"postalCode": "zipcode",
"addressTypeId": "addressType",
"primaryAddress": "primary"
}
},
"enrollmentDate": "enrollmentDate",
"expirationDate": "expirationDate"
}
В этом файле поля — это поля, которые мне нужно будет заполнить, а значения — это имена полей, которые я получаю из внешней системы, которая выглядит, например, так:
{
"user":"name",
"id":12345,
"active":true,
"type":"Student",
"group":"BA",
"dateCreated":"NOV 22 2019",
"lastLogin":"NOV 23 2020",
"lname":"Yard",
"fname":"Paul",
"email":"email@gmail.com",
"phone":"(000)-000-0000",
"mobile":"(000)-000-0000",
"birthDate":"OCT 11 1999",
"countryId": "US",
"addressLine1": "4th street",
"addressLine2": "25B",
"city": "NY",
"region": "NY",
"postalCode": "00000",
"addressTypeId": "Personal",
"primaryAddress": true,
"enrollmentDate": "MAR 22 2019",
"expirationDate": "MAR 21 2022"
}
Таким образом, конечный файл JSON должен выглядеть следующим образом:
{
"username":"name",
"externalSystemId":12345,
"active":true,
"type":"Student",
"patronGroup":"BA",
"meta": {
"creation_date":"NOV 22 2019",
"last_login_date":"NOV 23 2020"
},
"personal": {
"lastName":"Yard",
"firstName":"Paul",
"email":"email@gmail.com",
"phone":"(000)-000-0000",
"mobilePhone":"(000)-000-0000",
"dateOfBirth":"OCT 11 1999",
"addresses":{
"countryId": "US",
"addressLine1": "4th street",
"addressLine2": "25B",
"city": "NY",
"region": "NY",
"postalCode": "00000",
"addressTypeId": "Personal",
"primaryAddress": true
}
},
"enrollmentDate": "MAR 22 2019",
"expirationDate": "MAR 21 2022"
}
Я думал об использовании словаря / индекса для создания этого, но я никогда не делал этого раньше, и я не уверен, как это сделать.
Есть ли простой способ сделать это?
Ответ №1:
Такое сопоставление легко выполняется со словарем, когда у нас один уровень JSON.
Для многоуровневого JSON мы можем использовать рекурсивную функцию для сопоставления данных из словаря.
В коде допустим, что это ваш JSON:
let json = {
username: "user",
externalSystemId: "id",
active: "active",
type: "type",
patronGroup: "group",
meta: {
creation_date: "dateCreated",
last_login_date: "lastLogin",
},
personal: {
lastName: "lname",
firstName: "fname",
email: "email",
phone: "phone",
mobilePhone: "mobile",
dateOfBirth: "birthDate",
addresses: {
countryId: "countryCode",
addressLine1: "address",
addressLine2: "address2",
city: "city",
region: "region",
postalCode: "zipcode",
addressTypeId: "addressType",
primaryAddress: "primary",
},
},
enrollmentDate: "enrollmentDate",
expirationDate: "expirationDate",
};
// Here is the dictionary:
// Note: the personal address field had incorrect mapping for few fields, I have modified the property to match the value of respective key of the JSON.
let dictionary = {
user: "name",
id: 12345,
active: true,
type: "Student",
group: "BA",
dateCreated: "NOV 22 2019",
lastLogin: "NOV 23 2020",
lname: "Yard",
fname: "Paul",
email: "email@gmail.com",
phone: "(000)-000-0000",
mobile: "(000)-000-0000",
birthDate: "OCT 11 1999",
countryCode: "US",
address: "4th street",
address2: "25B",
city: "NY",
region: "NY",
zipcode: "00000",
addressType: "Personal",
primary: true,
enrollmentDate: "MAR 22 2019",
expirationDate: "MAR 21 2022",
};
// recursive function to map the JSON, extract the actual value from from dictionary
function buildMapping(jsonParam) {
let result = {};
// iterate over the JSON parameter
for (const [key, value] of Object.entries(jsonParam)) {
if (typeof value === "object") {
// for type as object, make a recursive call with the object value as param
// collect the result of inner object
let resultInner = buildMapping(value);
// attach the result of the inner object to its key
result[key] = resultInner;
} else {
// check if the dictionary contains the mapping, otherwise set as null
result[key] = dictionary.hasOwnProperty(value)
? dictionary[value]
: null;
}
}
return resu<
}
let resultJson = buildMapping(json);
console.log(resultJson);
Результат:
{
username: "name",
externalSystemId: 12345,
active: true,
type: "Student",
patronGroup: "BA",
meta: { creation_date: "NOV 22 2019", last_login_date: "NOV 23 2020" },
personal: {
lastName: "Yard",
firstName: "Paul",
email: "email@gmail.com",
phone: "(000)-000-0000",
mobilePhone: "(000)-000-0000",
dateOfBirth: "OCT 11 1999",
addresses: {
countryId: "US",
addressLine1: "4th street",
addressLine2: "25B",
city: "NY",
region: "NY",
postalCode: "00000",
addressTypeId: "Personal",
primaryAddress: true,
},
},
enrollmentDate: "MAR 22 2019",
expirationDate: "MAR 21 2022",
};
Комментарии:
1. Ах, вместо того, чтобы записывать все внутри одного раздела, я объявил входной JSON, словарь JSON и функцию один за другим, что сбивает с толку. Позвольте мне немного изменить форматирование. Если вы извлекаете словарь и вводите данные в свой JS-файл, вы можете передать параметр JSON, и словарь будет доступен.
2. Правильно ли
jsonParam
dictionary
выводится и в функции? в противном случае поделитесь сутью вашего последнего кода, чтобы я посмотрел?3. Я вижу, итак, вы добавили параметр в функцию
buildMapping
, вы также должны передать параметр при вызове функции изнутри:let resultInner = buildMapping(value, dictionary);
, теперь, когда вы его не передаете, он получает неопределенное значение.4. Также вам может потребоваться переключить словарь и данные
let test = buildMapping(settings.fieldMap, user);
в server.js5. Ах, это имеет смысл! Теперь я получаю ответы! Похоже, проблема с отображением, потому что некоторые поля возвращаются пустыми, а другие заполнены, так что, вероятно, это не проблема с кодом, а проблема с отображением, которую я могу выяснить! Большое вам спасибо!