Значения Json из одного файла на основе полей из другого файла Json

#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.js

5. Ах, это имеет смысл! Теперь я получаю ответы! Похоже, проблема с отображением, потому что некоторые поля возвращаются пустыми, а другие заполнены, так что, вероятно, это не проблема с кодом, а проблема с отображением, которую я могу выяснить! Большое вам спасибо!