Carol.Kar
Carol.Kar

Reputation: 5345

Object to formatted string

I am trying to transform my output into a character based formatted output.

I currently managed to output each category next to the product title.

let result = {
  "2": {
    "title": "Product 1",
    "category": [{
      "cat_name": "Category 1",
    }],
    "price": "99"
  },
  "3": {
    "title": "Product 2",
    "category": [{
      "cat_name": "Category 2",
    }],
    "price": "22"
  },
  "4": {
    "title": "Product 3",
    "category": [{
      "cat_name": "Category 1",
    }],
    "price": "55"
  }
}

let items = ""
for (var key in result) {
  items += `*${result[key].category["0"].cat_name}:* ->${result[key].title}  ($${result[key].price})` + "\n"
}

console.log(items)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

However, as output I would like to have:

*Category 1:* 
->Product 1  ($99)
->Product 3  ($55)

*Category 2:* 
->Product 2  ($22)

Any suggestions how to filter my result object that I get this output?

I appreciate your replies!

Upvotes: 1

Views: 59

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386540

You need to collect all categroies with their products first and then render the result.

var data = { 2: { title: "Product 1", category: [{ cat_name: "Category 1" }], price: "99" }, 3: { title: "Product 2", category: [{ cat_name: "Category 2" }], price: "22" }, 4: { title: "Product 3", category: [{ cat_name: "Category 1" }], price: "55" } },
    categories = Object.create(null);

Object.values(data).forEach(({ title, category, price }) =>
    category.forEach(({ cat_name }) =>
        (categories[cat_name] = categories[cat_name] || []).push({ title, price, cat_name })));

Object.entries(categories).forEach(([category, products]) => {
    console.log(`*${category}*:`);
    products.forEach(({ title, price }) => console.log(`->${title} ($${price})`));
});

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

Upvotes: 1

Jim Wright
Jim Wright

Reputation: 6058

A common way to do this would be to build an object for categories, and add each product into the related category. I have done this in the following snippet.

As in @NinaScholz's answer you could make the functions shorter but I decided to leave them like this so it is clearer what is happening.

let result = {
  "2": {
    "title": "Product 1",
    "category": [{
      "cat_name": "Category 1",
    }],
    "price": "99"
  },
  "3": {
    "title": "Product 2",
    "category": [{
      "cat_name": "Category 2",
    }],
    "price": "22"
  },
  "4": {
    "title": "Product 3",
    "category": [{
      "cat_name": "Category 1",
    }],
    "price": "55"
  }
}

const categories = {}
Object.keys(result).forEach((key) => {
    const item = result[key]
    const itemCategories = item.category
    itemCategories.forEach((category) => {
        if (!(category.cat_name in categories)) {
            categories[category.cat_name] = []
        }
        categories[category.cat_name].push({
            title: item.title,
            price: item.price
        })
    })
})

Object.keys(categories).forEach((category) => {
    console.log('*' + category + ':*')
    const items = categories[category]
    items.forEach((item) => {
        console.log('->' + item.title + ' ($' + item.price + ')')
    })
})

Upvotes: 1

Related Questions