таблица преобразования объекта javascript - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть объект, который мне нужно преобразовать, чтобы иметь возможность поместить его в HTML-таблицу .

Однако я изо всех сил пытаюсь понять, как я могу отобразить / преобразовать его, чтобы я мог повторить его, чтобы напечатать таблицу.

//Expected Output Table:
Week name | title 1 | title 2 | ...
Monday    | 12      | 34      | ...
Tuesday   | 14      | 36      | ...
...
const data = [
 {
  week: 'Monday',
  title: 'title 1',
  price: 12,
 },
 {
  week: 'Monday',
  title: 'title 2',
  price: 34,
 },
{
  week: 'Tuesday',
  title: 'title 1',
  price: 14,
 },
 {
  week: 'Tuesday',
  title: 'title 2',
  price: 36,
 },
 ...
]

data.map( item => {
   // this is the part I am stuck. 
   // can't get my head around it.
   return '<table>'
})

Я ожидаю, что результатом будет цикл или цикл с печатью заголовков таблицы и значений.

Ответы [ 4 ]

2 голосов
/ 01 апреля 2019

Я попытался изменить требование, добавив дополнительный заголовок.Также может случиться, что у какого-нибудь дня недели есть название, но нет другого.Предполагая 0 для тех, я создал эту таблицу.Код не оптимизирован, но вы определенно можете настроить его, удалив дополнительные forEach или используя Set

const data = [{
    week: 'Monday',
    title: 'title 1',
    price: 12,
  },
  {
    week: 'Monday',
    title: 'title 2',
    price: 34,
  },
  {
    week: 'Tuesday',
    title: 'title 3',
    price: 12,
  },
  {
    week: 'Wednesday',
    title: 'title 6',
    price: 34,
  },
  {
    week: 'Saturday',
    title: 'title 9',
    price: 34,
  },
  {
    week: 'Saturday',
    title: 'title 2',
    price: 24,
  },
  {
    week: 'Sunday',
    title: 'title 33',
    price: 255,
  }
]

/* create an object where keys will be name of the day and it's value will be
 an object again.
The object will looklike this
 'Monday':{
   'title 1':someValue,
   'title 2':someValue2,
   },{...}*/

let tableData = data.reduce(function(acc, curr) {
  acc[curr.week] ? acc[curr.week][curr.title] = curr.price :
    acc[curr.week] = {
      [curr.title]: curr.price
    }
  return acc;
}, {});

/* get all the keys from the newly created object and created an array like
['Monday','Tuesday'....]*/
let getKeys = Object.keys(tableData);

let getAllKeys = [];
for (let keys in tableData) {
  for (let elem in tableData[keys]) {
    if (!getAllKeys.includes(elem)) {
      getAllKeys.push(elem)
    }
  }
}

for (let keys in tableData) {
  let weekObj = Object.keys(tableData[keys]);
  getAllKeys.forEach(function(item) {
    if (!weekObj.includes(item)) {
      tableData[keys][item] = 0;
    }
  })
}
// creating table string
let tableStr = `<thead><tr><td>Week</td>`;
getAllKeys.forEach(function(item) {
  tableStr += `<td>${item}</td>`
})
tableStr += `</tr></thead><tbody><tr>`;
getKeys.forEach(function(item) {
  tableStr += `<td>${item}</td>`;
  let getWeekobj = tableData[item];
  getAllKeys.forEach(function(elem) {
    tableStr += `<td>${getWeekobj[elem]}</td>`
  });
  tableStr += `</tr>`;
})
tableStr += `</tbody>`
document.getElementById('tab').innerHTML = tableStr;
<table id='tab' border='1px solid black'></table>
0 голосов
/ 01 апреля 2019

Извините, мой потертый код, я написал бы что-нибудь лучше, если бы у меня было время.

let str = `<table><tr>${Object.keys(data[0]).map(item => `<th>${item}</th>`).join('')}</tr>`;
str += data.map(item => {
    let str = `<tr>`
    str += Object.values(item).map((value) => `<td>${value}</td>`).join('');
    str += `</tr>`
    return str
}).join('');
str += '</table>'

Вывод получается как

"<table><tr><th>week</th><th>title</th><th>price</th></tr><tr><td>Monday</td><td>title 1</td><td>12</td></tr><tr><td>Monday</td><td>title 2</td><td>34</td></tr></table>"
0 голосов
/ 01 апреля 2019

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

Например, если у вас был такой массив:

arr = [1, 2, 3, 4]

Вы можете получить массив со всеми значениями, удвоенными, используя карту следующим образом:

arr.map(e => e * 2) // => [2, 4, 6, 8]

Аналогично, если у вас есть массив объектов, вы можете отобразить его так, чтобы он создавал строки, которые представляют элементы HTML <tr> с такой же легкостью:

const data = [
 {
  week: 'Monday',
  title: 'title 1',
  price: 12,
 },
 {
  week: 'Monday',
  title: 'title 2',
  price: 34,
 },
 // ...
]

data.map(obj => `<tr>
    <td>Weekday: ${obj.week}</td>
    <td>Title: ${obj.title}</td>
    <td>Price: $${obj.price.toFixed(2)}</td>
</tr>`)

Это даст вам следующее:

[ '<tr>\n    <td>Weekday: Monday</td>\n    <td>Title: title 1</td>\n    <td>Price: $12.00</td>\n</tr>',
  '<tr>\n    <td>Weekday: Monday</td>\n    <td>Title: title 2</td>\n    <td>Price: $34.00</td>\n</tr>' ]

Затем вы можете применить join к этому, и вы готовы идти.

НО, есть лучший подход к этому: использовать reduce вместо map. В то время как map создает новый массив, reduce создает единственное значение, накапливая элементы вашего исходного массива, следуя определенному вами правилу.

Например, если я хотел получить сумму всех элементов в массиве:

let accumulator = (result, value) => result + value;
let startValue = 0;
[1, 2, 3, 4].reduce(accumulator, startValue) // => 10

Для вашего случая вы можете уменьшить data в строку:

const data = [
 {
  week: 'Monday',
  title: 'title 1',
  price: 12,
 },
 {
  week: 'Monday',
  title: 'title 2',
  price: 34,
 },
 // ...
]

const table = data.reduce((tbody, obj) => tbody + `<tr>
    <td>Weekday: ${obj.week}</td>
    <td>Title: ${obj.title}</td>
    <td>Price: $${obj.price.toFixed(2)}</td>
</tr>`, "<table>") + "</table>";
0 голосов
/ 01 апреля 2019

попробуйте преобразовать ваш объект в массив! с несколькими строками вроде этого:

Object.keys(data).map(key => 
<Tag/>
)

Вы можете перебирать объекты таким образом

также вы можете получить дочерний элемент по ключу (например: data [key] )

...