javascript对象转换表

时间:2019-04-01 10:43:18

标签: javascript ecmascript-6 ejs

我有一个对象,需要对其进行转换,才能将其放在 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 个答案:

答案 0 :(得分:2)

我试图通过添加其他标题来修改要求。也有可能某周的某天有一个标题而其他标题没有。假定这些为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>

答案 1 :(得分:0)

尝试将您的对象转换为数组! 像这样的几行:

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

您可以用这种方式迭代对象

此外,您还可以按键获取子元素(例如: data [key]

答案 2 :(得分:0)

不好意思,如果我有时间的话,我会写得更好。

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>"

答案 3 :(得分:0)

将map视为专门的foreach循环,它返回一个数组,该数组的值是应用于原始数组上每个元素的函数的返回值。

例如,如果您有一个像这样的数组:

arr = [1, 2, 3, 4]

通过使用map,您可以获得所有值加倍的数组:

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代替mapmap产生一个新数组,而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>";