Сопоставление массива объектов с неизвестными ключами или длинами

У меня есть некоторые данные, которые я пытаюсь вывести в Excel. Мои обычные функции, которые правильно работают с «обычными» данными, вызывают у меня проблемы, в частности, я вижу undefined для возвращаемых массивов в моей переменной MappedArrays и, кажется, теряю одну строку данных.

Я попытался упростить проблему, чтобы создать MCVE, это может быть даже не проблема, но я хотел бы, чтобы моя основная функция могла правильно обрабатывать это.

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

В настоящее время у меня есть функция, позволяющая убедиться, что каждый объект имеет каждый ключ (это необходимо для вставки данных в Excel, значение может быть null).

У меня есть еще одна функция для преобразования массива объектов в массив сопоставленных массивов, где все значения должны быть в позиции по индексу.

В моих тестовых данных у меня есть строка "Header_E": "Test", в одном объекте, которая в настоящее время выводится в том, что выглядит как ее индекс в объекте, она должна быть соотнесена с индексом заголовка/столбца.

Header_A    Header_B    Header_C    Header_D    Header_E    Header_F
2AVal       2BVal               
3AVal       3BVal               
4AVal       4BVal       4DVal           
                        Test    

Как я могу гарантировать, что все объекты в массиве объектов имеют все ключи, а затем сопоставить эти ArrOfObjs с массивом с данными, проиндексированными в соответствии с ключом объекта

Вот мой образец данных:

async function CommandsFunc(event) {
    try {
        await Excel.run(async (context) => {
            //Start Func.

            var ws = context.workbook.worksheets.getActiveWorksheet();

            var Obj_One_A = {
                "Header_A": "2AVal",
                "Header_B": "2BVal",
            }

            var Obj_Two_A = {
                "Header_A": "3AVal",
                "Header_B": "3BVal",
            }

            var Obj_One_B = {
                "Header_A": "4AVal",
                "Header_B": "4BVal",
                "Header_D": "4DVal",
            }

            var Obj_Two_B = {
                "Header_A": "",
                "Header_C": "",
                "Header_E": "Test",
                "Header_F": "",
            }

            var Arr_Of_Items = [Obj_One_A, Obj_Two_A]

            //await Do_Arr_Of_Objs_Or_Arrs_To_Rng(context, ws, Arr_Of_Items)

            var HeaderArr = ["Header_A", "Header_B"]
            var MappedArrays = await Get_Mapped_Over_Array_Of_Objects(Arr_Of_Items, HeaderArr)
            MappedArrays.unshift(HeaderArr)

            var rng = ws.getRangeByIndexes(0, 0, MappedArrays.length, MappedArrays[0].length)

            rng.select()
            await context.sync();
            rng.values = MappedArrays
            await context.sync();       

            var Arr_Of_Items = [Obj_One_B, Obj_Two_B]
            var All_Headers_Arr = ["Header_A", "Header_B", "Header_C", "Header_D", "Header_E", "Header_F"]
            var MappedArrays = await Get_Mapped_Over_Array_Of_Objects(Arr_Of_Items, All_Headers_Arr)

            var Used_Rng = ws.getUsedRange(true)
            Used_Rng.load('rowCount')
            await context.sync()
            var rng = ws.getRangeByIndexes(Used_Rng.rowCount, 0, MappedArrays.length, All_Headers_Arr.length)

            //Set Headers
            for (let ai = 0; ai < All_Headers_Arr.length; ai++) {
                ws.getUsedRange(true).getRow(0).getCell(0, ai).values = All_Headers_Arr[ai]
            }

            rng.select()
            await context.sync();
            rng.values = MappedArrays
            await context.sync();

            //await Do_Arr_Of_Objs_Or_Arrs_To_Rng(context, ws, Arr_Of_Items)

            //End Func
            await context.sync();
        });
    } catch (error) {
        console.log(error)        
    }
    try { event.completed() } catch (error) { }
}   

Вспомогательные функции:

async function Get_Mapped_Over_Array_Of_Objects(ArrayOfObjs, MapArr) {
    ArrayOfObjs = await Do_All_Arr_Of_Objs_Same_Keys(ArrayOfObjs, MapArr)
    let MappedArrays = []
    for (let i = 0; i < ArrayOfObjs.length; i++) {
        var obj = ArrayOfObjs[i]
        var arr = Object.keys(obj).map((k) => obj[k])
        MappedArrays.push(arr)
    }
    return MappedArrays;
}

async function Do_All_Arr_Of_Objs_Same_Keys(Arr_Of_Objs, Keys_Arr) {
    for (let oi = 0; oi < Arr_Of_Objs.length; oi++) {
        var obj = Arr_Of_Objs[oi]
        var Obj_Keys = Object.keys(obj)
        if (Keys_Arr.length != Obj_Keys.length) {
            var temp_arr = []
            temp_arr = Keys_Arr
            for (let ki = 0; ki < Obj_Keys.length; ki++) {
                temp_arr = await Do_Remove_Arr_By_Val(temp_arr, Obj_Keys[ki])
            }
            for (let ai = 0; ai < temp_arr.length; ai++) {
                obj[temp_arr[ai]] = ""
            }
        }
    }
    return Arr_Of_Objs
}

function Do_Remove_Arr_By_Val(arr, val) {
    var filteredArray = arr.filter(function (e) { return e !== val })
    return filteredArray
}
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
0
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша проблема возникает из этой строки:

var arr = Object.keys(obj).map((k) => obj[k])

Это помещает значения в arr в том порядке, в котором ключи определены в объекте, что не обязательно одинаково для каждого объекта. Вы заметите, что в третьей строке вашего примера вывода у вас есть значение для Header_D в столбце Header_C, что является проявлением той же проблемы.

Поскольку вы знаете, что каждый объект имеет одинаковый набор ключей, когда вы доберетесь до этой функции, вы должны перебирать этот постоянный список ключей (All_Headers_Arr) вместо Object.keys(obj). Это обеспечит постоянную индексацию всех значений arr.

Сказав это, я думаю, что есть также потенциал для упрощения вашего кода в соответствии с этим фрагментом.

var Obj_One_A = { "Header_A": "2AVal", "Header_B": "2BVal" }

var Obj_Two_A = { "Header_A": "3AVal", "Header_B": "3BVal" }

var Obj_One_B = { "Header_A": "4AVal", "Header_B": "4BVal", "Header_D": "4DVal" }

var Obj_Two_B = { "Header_A": "", "Header_C": "", "Header_E": "Test", "Header_F": "" }

var Arr_Of_Items = [Obj_One_A, Obj_Two_A, Obj_One_B, Obj_Two_B]

// get a list of unique headers
let Headers = new Set()
Arr_Of_Items
  .forEach(o => Object.keys(o)
    .forEach(k => Headers.add(k))
  )

// convert to an array
All_Headers = Array.from(Headers.values()).sort()

// make sure each object has all the headers, assigning null values to any missing headers
const MappedArrays = Arr_Of_Items
  .map(o => All_Headers
    .map(h => o.hasOwnProperty(h) ? o[h] : null)
  )

console.log(MappedArrays)

Спасибо, мне нравится функция карты для помещения JSON в таблицу, но мне нужно больше в ней разбираться. Плюсы и минусы JS в том, что в сети есть функции для всего, что я могу собрать воедино. TBH, мне трудно читать этот код, но чем больше я его использую, тем больше узнаю. Это помогло мне сразу понять мой другой код, моя основная проблема заключалась в неправильном выборе диапазона, но также это нужно было исправить.

FreeSoftwareServers 23.04.2022 11:35

Я не хочу сказать, что код написан плохо, мне просто нужно научиться читать стрелочные функции и синтаксис карт. Я тоже пока не понимаю ?. Во всяком случае, Google может дать мне всю эту информацию!

FreeSoftwareServers 23.04.2022 11:37

@FreeSoftwareServers да, к синтаксису стрелочных функций нужно немного привыкнуть, и иногда он может сделать код немного трудным для понимания, но в целом я думаю, что это огромный шаг вперед в написании лаконичного кода. Что касается ?, это тернарный оператор. В любом случае, я рад, что это помогло вам.

Nick 24.04.2022 00:35

Другие вопросы по теме