简体   繁体   中英

How to add <hr> after every new category

I have a array of object called elements, and the objects have two values ( name and category ).

[
  {name : 'key1', category : 'tech'},
  {name : 'key2', category : 'tech'},
  {name : 'key3', category : 'tech'},
  {name : 'cable1' , category : 'hard'}
  {name : 'cable2' , category : 'hard'}
  {name : 'cable3' , category : 'hard'}
  {name : 'cable4' , category : 'hard'}
]

I want to display all names but add an <hr> whenever reaches a new category

Please help and thank you of helping.

I would first group your objects by category using Array.prototype.reduce() , then iterate over each category using Array.prototype.map() :

 const data = [ {name : 'key1', category : 'tech'}, {name : 'wire1' , category : 'misc'}, {name : 'key2', category : 'tech'}, {name : 'cable1' , category : 'hard'}, {name : 'key3', category : 'tech'}, {name : 'cable2' , category : 'hard'}, {name : 'wire2' , category : 'misc'} ]; const dataMap = data.reduce((acc, x) => { acc[x.category] = [...(acc[x.category] || []), x]; return acc; }, {}); const html = Object.entries(dataMap).map(([cat, items]) => { return items.map(item => `<div>${item.name} ${item.category}</div>`).join(''); }).join('<hr>'); document.getElementById('app').innerHTML = html;
 <div id="app"></div>

How about something like:

prev_category = undefined;
elements.forEach(function(e) {
  if (i > 0 && e.category != prev_category) {
    console.log('<hr>');
  }

  prev_category = e.category;
  console.log(e.name);
});

(of course, you can replace the console.log() commands with whatever you really want to do with those texts, eg append them to one big string)

You can try something like this,

var category;
$.each(object,function(i,objval)
{
   console.log(objval['name']);
   if(category != "" && category != objval['category'])
   {
     console.log("<hr>");
   }
   category = objval['category'];
});

Iterate the object and use template literals to create the dom and check if the index of the array is not same as length then add an hr

 let elements = [{ name: 'key', category: 'tech' }, { name: 'cable', category: 'hard' } ] let str = ''; elements.forEach(function(item, index) { str += `<div class='elem'><span>${item.name}</span><span> ${item.category}</span></div>` if (index !== elements.length - 1) { str += `<hr>` } }); document.getElementById('container').innerHTML = str
 <div id='container'></div>

If you are looking for just border then use css pseudo selector

 let elements = [{ name: 'key', category: 'tech' }, { name: 'cable', category: 'hard' } ] let str = ''; elements.forEach(function(item, index) { str += `<div class='elem'><span>${item.name}</span><span> ${item.category}</span></div>` }); document.getElementById('container').innerHTML = str
 .elem:not(:last-child) { border-bottom: 1px solid black; }
 <div id='container'></div>

Basically you need to sort the data by category first then, render the element, I use react code as example

const data = [
  {
    name: "Huawei",
    category: "phone"
  },
  {
    name: "Iphone",
    category: "phone"
  },
  {
    name: "Refacoring Improving the design of existing code",
    category: "book"
  },
  {
    name: "Python Crash Course",
    category: "book"
  },
  {
    name: "My heart will go on",
    category: "music"
  },
  {
    name: "I'm your angel",
    category: "music"
  }
];

function generateCom(data) {
  let listComps = [];
  let category = "";

  // sort the data by category
  data.sort((a, b) => (a.category > b.category ? 1 : -1));

  // generate the component by category
  data.forEach((ele, idx) => {
    if (idx === 0) {
      listComps.push(<h3>{ele.category}</h3>);
      listComps.push(<li>{ele.name}</li>);
      category = ele.category;
      return;
    }

    if (ele.category === category) {
      listComps.push(<li>{ele.name}</li>);
    } else {
      listComps.push(<hr />);
      listComps.push(<h3>{ele.category}</h3>);
      listComps.push(<li>{ele.name} </li>);
      category = ele.category;
    }
  });
  return listComps;
}

can refer to the example https://codesandbox.io/embed/6x0p7908qw

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM