Как я могу создать конструктор для массива объектов в JavaScript? - PullRequest
1 голос
/ 23 апреля 2020

Я пытаюсь создать объект во время выполнения для представления тиков по вертикальной оси для диаграммы Google.

Учитывая массив номеров нот MIDI (https://newt.phys.unsw.edu.au/jw/notes.html) nn, где диапазон определяется пользователем, мне нужно преобразовать его в массив объектов вида {v: nn, f: notes [nn]}

(notes - это существующий массив текста имена, такие как «C4» для nn = 60).

notes = ['A0', 'A#0', 'B0', 'C1', ... , 'C8'] 

и соответствующие значения nn будут:

nnArr = [21, 22, 23, 24, ... , 108] 

Конечные результаты будут выглядеть примерно так:

vAxisTicks= [
  {v: 56, f: notes[56-21]}, {v: 57, f: notes[57-21}, {v: 58, f: notes[58-21]}
]

et c

Я думаю, что подход состоит в том, чтобы использовать Array с .map, но я не могу понять, как использовать это для получения ключей в объектах, несмотря на несколько вылазок в литература!

1 Ответ

1 голос
/ 23 апреля 2020

Если я правильно понял, вы хотите сгенерировать как это?:

const notes = {};
const letters = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'];
let num = 0;

for (let i = 21, y = 0; i <= 108; i++, y >= letters.length - 1 ? y = 0 : y++){
  if (letters[y] == "C") num ++;
  notes[i] = letters[y] + num;
}

//console.log(notes)

const output = Object.entries(notes).map(([key,val]) => {
  return {v: key, f: val}
});
console.log(output)

//It could be generated in one loop with:
/*
const notesArr = [];
for (let i = 21, y = 0; i <= 108; i++, y >= letters.length - 1 ? y = 0 : y++){
  if (letters[y] == "C") num ++;
  notesArr.push({v: i, f: letters[y] + num});
}
console.log(notesArr)
*/
.as-console-wrapper { max-height: 100% !important; top: 0; }

Вывод:

[
  {
    "v": "21",
    "f": "A0"
  },
  {
    "v": "22",
    "f": "A#0"
  },
  {
    "v": "23",
    "f": "B0"
  },
  {
    "v": "24",
    "f": "C1"
  },
  ...
]

Важны следующие строки:

for (let i = 21, y = 0; i <= 108; i++, y >= letters.length - 1 ? y = 0 : y++){
  if (letters[y] == "C") num ++;
  notes[i] = letters[y] + num;
}

, что означает l oop от i = 21 до i = 108 - я получил это от: https://newt.phys.unsw.edu.au/jw/notes.html.

Каждая итерация l oop добавляет один к i и добавляет один к y, если y уже не равен последнему индексу массива букв:

const letters = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'];

, если он находится в конце (поэтому y == 11), затем сбросить на ноль: y = 0 .

Затем вы создали объект заметок, такой как:

{21: 'A0', 22: 'A#0', 23: 'B0', 24: 'C1', ... , 108: 'C8'}

Затем вы можете l oop поверх записей с помощью Object.entries(notes).

Это дает вам массив, подобный этому:

[[21, 'A0'], [22, 'A#0'], [23, 'B0'], [24, 'C1'], ... , [108, 'C8']]

Который вы можете l oop использовать .map() для создания желаемого результата.

ПРИМЕЧАНИЕ: мы могли только что создать это заранее в for-l oop, но кажется, что у вас уже есть этот объект заметок.

В качестве альтернативы:

Если вы хотите взять массив как ввод [56, 57, 58]

Затем вы можете сделать это:

const notes = {};
const letters = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'];
let num = 0;

for (let i = 21, y = 0; i <= 108; i++, y >= letters.length - 1 ? y = 0 : y++){
  if (letters[y] == "C") num++;
  notes[i] = letters[y] + num;
}

//console.log(notes)

const inputNums = [56, 57, 58];

const output = inputNums.map(item => {
  return {v: item, f: notes[item]}
});

console.log(output)
.as-console-wrapper { max-height: 100% !important; top: 0; }

вывод:

[
  {
    "v": 56,
    "f": "G#3"
  },
  {
    "v": 57,
    "f": "A3"
  },
  {
    "v": 58,
    "f": "A#3"
  }
]

В качестве альтернативы:

Если я предполагаю, что я только что отредактировал Ваш вопрос, что у вас есть массив для заметок, таких как:

notes = ['A0', 'A#0', 'B0', 'C1', ... , 'C8'] 

и соответствующие значения nn будут:

nnArr = [21, 22, 23, 24, ... , 108] 

Тогда мы можем решить его очень похожим образом:

const notes = [];
const letters = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'];
let num = 0;

for (let i = 21, y = 0; i <= 108; i++, y >= letters.length - 1 ? y = 0 : y++){
  if (letters[y] == "C") num++;
  notes.push(letters[y] + num);
}
//console.log(notes)

const input = [56, 57, 58]

const output = input.map(i => {
  return {v: i, f: notes[i - 21]}
});
console.log(output)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...