Преобразование 3 массивов в объект

Добрый день, приятель, я пытаюсь преобразовать 3 массива в 1 объект. Мне нужно, чтобы длина массива каждого месяца соответствовала длине другого массива Если у кого-то есть идеи, как это решить, я был бы очень признателен. Спасибо, что уделили время и прочитали это, хорошего дня!

Данные:

const months = [
    "March 2022",
    "April 2022",
    "May 2022",
    "June 2022"
]

const values = [
    [ "-50" ],
    [ "-100",  "350", "-111" ],
    [ "201", "200" ],
    [ "-290" ]
]

const categories = [
    [ "Credit" ],
    [ "Debt", "Salary", "Credit" ],
    [ "Salary", "Salary" ],
    [ "Investments" ]
]

Это ожидаемый результат:

[
    {
        "name": "March 2022",
        "series": 
            { 
                "name": "Credit" , 
                "value": -50 
            }
        
    },
    {
        "name": "April 2022",
        "series": [
            {
                "name": "Debt",
                "value": -100
            },
            {
                "name": "Salary",
                "value": 350
            },
            {
                "name": "Credit",
                "value": -111
            }
        ]
    },
    {
        "name": "May 2022",
        "series": [
            {
                "name": "Salary",
                "value": 201
            },
            {
                "name": "Salary",
                "value": 200
            }
        ]
    },
    {
        "name": "June 2022",
        "series":
            {
                "name": "Investments",
                "value": -290
            }
        
    }
]

Все, что я делал в последние дни, это этот код, но он не работает, раньше для длины вторых элементов он работал, но когда длина 3-го элемента увеличилась, они начали ставить вместе, и это еще не все. Я использую angular, и при переходе с 1 маршрута на другой их длина по индексу [i] начинает делать ставку (если вручную обновить страницу с помощью crtl + r, она работает).. Когда сначала вызывается цикл for из console.log(values[i] .length) его длина равна [1, 3, 2, 1], что правильно, но при следующем вызове (при переходе на страницы) длина равна [2, 6, 4, 2] и увеличивается с каждым вызовом:

const months = [
  "March 2022",
  "April 2022",
  "May 2022",
  "June 2022"
]

const values = [
  ["-50"],
  ["-100", "350", "-111"],
  ["201", "200"],
  ["-290"]
]

const categories = [
  ["Credit"],
  ["Debt", "Salary", "Credit"],
  ["Salary", "Salary"],
  ["Investments"]
]

let result = [];
let subArray1 = [];
let subArray2 = [];

for (let i = 0; i < values.length; i++) {

  // if 1 expense per month push to subArray1 => result
  if (values[i].length == 1) {
    subArray1.push([{
      "name": categories[i],
      "value": +values[i]
    }])
  } else {

    for (let j = 0; j < values[i].length; j++) {
      // if more then 1 expense per month push to subArray2 => subArray1 => result
      subArray2.push({
        "name": categories[i][j],
        "value": +values[i][j]
      });
    };
    subArray1.push(subArray2);
  };
};


//combine all together
for (let i = 0; i < months.length; i++) {
  result.push({
    "name": months[i],
    "series": subArray1[i]
  });
};
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
48
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Чтобы добиться вашего результата, я создал функцию, которая создает массив series, и основную функцию, которая использует в нем функцию series.

let months = [
  "March 2022",
  "April 2022",
  "May 2022",
  "June 2022"
]

let values = [
  ["-50"],
  ["-100", "350", "-111"],
  ["201", "200"],
  ["-290"]
]

const categories = [
  ["Credit"],
  ["Debt", "Salary", "Credit"],
  ["Salary", "Salary"],
  ["Investments"]
]

const mapSeries = (index) => (values[index] || []).map((value, vindex) => ({
  name: categories[index][vindex],
  value
}))

const output = months.map((name, index) => ({
  name,
  series: mapSeries(index)
}))

console.log(output)

Примечание: Если длина каждого массива элементов values и categories не одинакова, то в функции mapSeries мы можем сделать что-то вроде categories[index]?.[vindex] || 'not assigned'), чтобы избежать ошибок.

Это хороший ответ, и вы показали мне новый лучший способ с меньшим количеством кода и лучшей читабельностью. Только я сделал небольшое изменение «значение: + значение», чтобы оно было числом, потому что согласно вашему коду ['-50'], который является строкой массива

Aleks_thunder 23.04.2022 10:29

Вы почти у цели, вам просто нужно небольшое изменение в вашем коде, и все будет хорошо.

  1. Вам нужно инициализировать subArray2 внутри цикла на каждой итерации, так как нам каждый раз нужен отдельный массив.
  2. Вы можете отказаться от условия, поскольку внутренний цикл for в любом случае позаботится об этом независимо от количества значений.

let months = ["March 2022","April 2022","May 2022","June 2022"]
let values = [["-50"],["-100", "350", "-111"],["201", "200"],["-290"]]
const categories = [["Credit"],["Debt", "Salary", "Credit"],["Salary", "Salary"],["Investments"]]

let result = [];
let subArray1 = [];

for (let i = 0; i < values.length; i++) {
    let subArray2 = [];
    for (let j = 0; j < values[i].length; j++) {
      subArray2.push({
        "name": categories[i][j],
        "value": +values[i][j]
    });
  };
  subArray1.push(subArray2)
};

//combine all together
for (let i = 0; i < months.length; i++) {
  result.push({
    "name": months[i],
    "series": subArray1[i]
  });
};

console.log(result)

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

Aleks_thunder 23.04.2022 10:33

Не беспокойтесь, я хотел помочь, я сделал, и я доволен этим ?

Code Maniac 23.04.2022 10:39

Вы можете сгенерировать нужные результаты с помощью вложенного map, сначала для имени month, а затем для categories, используя второй (index) параметр обратного вызова, чтобы выбрать соответствующие значения из других массивов:

const months = [
  "March 2022",
  "April 2022",
  "May 2022",
  "June 2022"
]

const values = [
  ["-50"],
  ["-100", "350", "-111"],
  ["201", "200"],
  ["-290"]
]

const categories = [
  ["Credit"],
  ["Debt", "Salary", "Credit"],
  ["Salary", "Salary"],
  ["Investments"]
]

const result = months.map((m, mnum) => ({
  name: m,
  series: categories[mnum].map((c, cnum) => ({
    name: c,
    value: +values[mnum][cnum]
  }))
}))

console.log(result)

Обратите внимание, что этот код всегда возвращает массив для series, кажется, это было бы проще обработать, чем пытаться выяснить, был ли это массив или объект.

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