DRY-er way of displaying items from an array with subcategories












0















I'm creating a menu page using React and Redux. I currently have the entire menu of over 100 items on an array of objects, which includes a 'category' property for the type of food (appetizers, burgers, desserts, etc.)



I originally just mapped through all of the items and rendered them all like this:



render(){
let foodList = this.props.foodMenu.map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))

return (
<div >
<h2>Food Menu</h2>
{foodList}
</div>
)


However, I want to be able to separate the menu by categories, which led me to this:



    render(){
let appetizers = this.props.foodMenu.filter(food => food.category === 'appetizers').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))

let soupsalad = this.props.foodMenu.filter(food => food.category === 'soupsalad').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))


let steaks = this.props.foodMenu.filter(food => food.category === 'steaks').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))


return (
<div>
<h2>Food Menu</h2>
<h3>Appetizers</h3>
<div className='container'>
{appetizers}
</div>
<h3>Soup or Salad</h3>
<div className='container'>
{soupsalad}
</div>
<h3>Steak</h3>
<div className='container'>
{steaks}
</div>
</div>


Except instead of 3 categories, I have 12. As you can see, this starts to become extremely repetitive and not "DRY". I was wondering if there was a cleaner way to go about doing this?










share|improve this question























  • Group by then iterate through them. stackoverflow.com/questions/14446511/…

    – Ortho Home Defense
    Nov 28 '18 at 23:15











  • If I do a group by in my database and send it back to my state, I would still need to map through each individual category. Is there another way I could do this?

    – Justin C.
    Nov 29 '18 at 1:28











  • You could take that answer and turn it into an array of objects that looks like [{value: "value1", category: [...every item for that category]}, {value: "value2", category: [...every item for that category]}]. Then you just iterate through that and use something like your original method to create the html.

    – Ortho Home Defense
    Nov 29 '18 at 14:58


















0















I'm creating a menu page using React and Redux. I currently have the entire menu of over 100 items on an array of objects, which includes a 'category' property for the type of food (appetizers, burgers, desserts, etc.)



I originally just mapped through all of the items and rendered them all like this:



render(){
let foodList = this.props.foodMenu.map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))

return (
<div >
<h2>Food Menu</h2>
{foodList}
</div>
)


However, I want to be able to separate the menu by categories, which led me to this:



    render(){
let appetizers = this.props.foodMenu.filter(food => food.category === 'appetizers').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))

let soupsalad = this.props.foodMenu.filter(food => food.category === 'soupsalad').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))


let steaks = this.props.foodMenu.filter(food => food.category === 'steaks').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))


return (
<div>
<h2>Food Menu</h2>
<h3>Appetizers</h3>
<div className='container'>
{appetizers}
</div>
<h3>Soup or Salad</h3>
<div className='container'>
{soupsalad}
</div>
<h3>Steak</h3>
<div className='container'>
{steaks}
</div>
</div>


Except instead of 3 categories, I have 12. As you can see, this starts to become extremely repetitive and not "DRY". I was wondering if there was a cleaner way to go about doing this?










share|improve this question























  • Group by then iterate through them. stackoverflow.com/questions/14446511/…

    – Ortho Home Defense
    Nov 28 '18 at 23:15











  • If I do a group by in my database and send it back to my state, I would still need to map through each individual category. Is there another way I could do this?

    – Justin C.
    Nov 29 '18 at 1:28











  • You could take that answer and turn it into an array of objects that looks like [{value: "value1", category: [...every item for that category]}, {value: "value2", category: [...every item for that category]}]. Then you just iterate through that and use something like your original method to create the html.

    – Ortho Home Defense
    Nov 29 '18 at 14:58
















0












0








0


1






I'm creating a menu page using React and Redux. I currently have the entire menu of over 100 items on an array of objects, which includes a 'category' property for the type of food (appetizers, burgers, desserts, etc.)



I originally just mapped through all of the items and rendered them all like this:



render(){
let foodList = this.props.foodMenu.map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))

return (
<div >
<h2>Food Menu</h2>
{foodList}
</div>
)


However, I want to be able to separate the menu by categories, which led me to this:



    render(){
let appetizers = this.props.foodMenu.filter(food => food.category === 'appetizers').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))

let soupsalad = this.props.foodMenu.filter(food => food.category === 'soupsalad').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))


let steaks = this.props.foodMenu.filter(food => food.category === 'steaks').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))


return (
<div>
<h2>Food Menu</h2>
<h3>Appetizers</h3>
<div className='container'>
{appetizers}
</div>
<h3>Soup or Salad</h3>
<div className='container'>
{soupsalad}
</div>
<h3>Steak</h3>
<div className='container'>
{steaks}
</div>
</div>


Except instead of 3 categories, I have 12. As you can see, this starts to become extremely repetitive and not "DRY". I was wondering if there was a cleaner way to go about doing this?










share|improve this question














I'm creating a menu page using React and Redux. I currently have the entire menu of over 100 items on an array of objects, which includes a 'category' property for the type of food (appetizers, burgers, desserts, etc.)



I originally just mapped through all of the items and rendered them all like this:



render(){
let foodList = this.props.foodMenu.map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))

return (
<div >
<h2>Food Menu</h2>
{foodList}
</div>
)


However, I want to be able to separate the menu by categories, which led me to this:



    render(){
let appetizers = this.props.foodMenu.filter(food => food.category === 'appetizers').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))

let soupsalad = this.props.foodMenu.filter(food => food.category === 'soupsalad').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))


let steaks = this.props.foodMenu.filter(food => food.category === 'steaks').map((food) => (
<Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
))


return (
<div>
<h2>Food Menu</h2>
<h3>Appetizers</h3>
<div className='container'>
{appetizers}
</div>
<h3>Soup or Salad</h3>
<div className='container'>
{soupsalad}
</div>
<h3>Steak</h3>
<div className='container'>
{steaks}
</div>
</div>


Except instead of 3 categories, I have 12. As you can see, this starts to become extremely repetitive and not "DRY". I was wondering if there was a cleaner way to go about doing this?







reactjs react-redux dry






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 28 '18 at 23:10









Justin C.Justin C.

475




475













  • Group by then iterate through them. stackoverflow.com/questions/14446511/…

    – Ortho Home Defense
    Nov 28 '18 at 23:15











  • If I do a group by in my database and send it back to my state, I would still need to map through each individual category. Is there another way I could do this?

    – Justin C.
    Nov 29 '18 at 1:28











  • You could take that answer and turn it into an array of objects that looks like [{value: "value1", category: [...every item for that category]}, {value: "value2", category: [...every item for that category]}]. Then you just iterate through that and use something like your original method to create the html.

    – Ortho Home Defense
    Nov 29 '18 at 14:58





















  • Group by then iterate through them. stackoverflow.com/questions/14446511/…

    – Ortho Home Defense
    Nov 28 '18 at 23:15











  • If I do a group by in my database and send it back to my state, I would still need to map through each individual category. Is there another way I could do this?

    – Justin C.
    Nov 29 '18 at 1:28











  • You could take that answer and turn it into an array of objects that looks like [{value: "value1", category: [...every item for that category]}, {value: "value2", category: [...every item for that category]}]. Then you just iterate through that and use something like your original method to create the html.

    – Ortho Home Defense
    Nov 29 '18 at 14:58



















Group by then iterate through them. stackoverflow.com/questions/14446511/…

– Ortho Home Defense
Nov 28 '18 at 23:15





Group by then iterate through them. stackoverflow.com/questions/14446511/…

– Ortho Home Defense
Nov 28 '18 at 23:15













If I do a group by in my database and send it back to my state, I would still need to map through each individual category. Is there another way I could do this?

– Justin C.
Nov 29 '18 at 1:28





If I do a group by in my database and send it back to my state, I would still need to map through each individual category. Is there another way I could do this?

– Justin C.
Nov 29 '18 at 1:28













You could take that answer and turn it into an array of objects that looks like [{value: "value1", category: [...every item for that category]}, {value: "value2", category: [...every item for that category]}]. Then you just iterate through that and use something like your original method to create the html.

– Ortho Home Defense
Nov 29 '18 at 14:58







You could take that answer and turn it into an array of objects that looks like [{value: "value1", category: [...every item for that category]}, {value: "value2", category: [...every item for that category]}]. Then you just iterate through that and use something like your original method to create the html.

– Ortho Home Defense
Nov 29 '18 at 14:58














2 Answers
2






active

oldest

votes


















1














Based on previous answer I decided to make a real working solution of that. I also added another way of doing this with the forEach method. Please do run the snippet to see the results.



Cheers!






const Food = props => {
//Do something that make sense with this :)
const { food, addToCart, className } = props;
return (
<React.Fragment>
Food: {food.id} <br />
</React.Fragment>
);
};

const App = props => {
const categories = {
Appetizers: "appetizers",
Soupsalad: "soupsalad",
Steaks: "steaks"
};

var menus1 = ;
Object.keys(categories).forEach(categorie => {
var subMenus = props.foodMenu
.filter(food => food.category === categories[categorie])
.map((food,i) => (
<div key={i}>
<h3>{categorie}</h3>
<div className="container">
<Food
className="food-menu"
key={food.id}
food={food}
addToCart={""}
/>
</div>
</div>
));
menus1 = [...menus1, subMenus];
});

const menus2 = Object.entries(categories).map(e => {
return props.foodMenu
.filter(food => food.category === e[1])
.map((food,i) => (
<div key={i}>
<h3>{e[0]}</h3>
<div className="container">
<Food
className="food-menu"
key={food.id}
food={food}
addToCart={""}
/>
</div>
</div>
));
});

return (
<React.Fragment>
<h2>Food Menu1 with foreach</h2>
{menus1}

<h2>Food Menu2 with map of map</h2>
{menus2}
</React.Fragment>
);
};


var foodMenu = [
{ id: "food1", category: "appetizers" },
{ id: "food2", category: "soupsalad" },
{ id: "food3", category: "steaks" }
];
const rootElement = document.getElementById("root");
ReactDOM.render(<App foodMenu={foodMenu} />, rootElement);

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>








share|improve this answer


























  • Great answer! I posted something I found today that worked as well. Thanks!

    – Justin C.
    Nov 30 '18 at 2:41



















1














@geostack posted a great answer. Here is also something I found worked for my application.



const sortByCategory = (dataArray) => {
let sortedByCategory = {}
dataArray.forEach(item => {
if (sortedByCategory[item.category]) {
sortedByCategory[item.category].push(item)
} else {
sortedByCategory[item.category] =
sortedByCategory[item.category].push(item)
}
})
return sortedByCategory
}

render(){
let sortedData = sortByCategory(this.props.foodMenu)
let foodMenu =

for(let key in sortedData) {
foodMenu.push(
<div >
<h3>{key.toUpperCase()}</h3>
<br />
<div>
{
sortedData[key].map(food => {
return (
<div key={food.id}>
<Food key={food.id} food={food} addToCart={this.addToCart}/>
<hr />
</div>
)
})
}
</div>
</div>
)
}

return (
<div>
{foodMenu}
</div>
)
}





share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53529500%2fdry-er-way-of-displaying-items-from-an-array-with-subcategories%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Based on previous answer I decided to make a real working solution of that. I also added another way of doing this with the forEach method. Please do run the snippet to see the results.



    Cheers!






    const Food = props => {
    //Do something that make sense with this :)
    const { food, addToCart, className } = props;
    return (
    <React.Fragment>
    Food: {food.id} <br />
    </React.Fragment>
    );
    };

    const App = props => {
    const categories = {
    Appetizers: "appetizers",
    Soupsalad: "soupsalad",
    Steaks: "steaks"
    };

    var menus1 = ;
    Object.keys(categories).forEach(categorie => {
    var subMenus = props.foodMenu
    .filter(food => food.category === categories[categorie])
    .map((food,i) => (
    <div key={i}>
    <h3>{categorie}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    menus1 = [...menus1, subMenus];
    });

    const menus2 = Object.entries(categories).map(e => {
    return props.foodMenu
    .filter(food => food.category === e[1])
    .map((food,i) => (
    <div key={i}>
    <h3>{e[0]}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    });

    return (
    <React.Fragment>
    <h2>Food Menu1 with foreach</h2>
    {menus1}

    <h2>Food Menu2 with map of map</h2>
    {menus2}
    </React.Fragment>
    );
    };


    var foodMenu = [
    { id: "food1", category: "appetizers" },
    { id: "food2", category: "soupsalad" },
    { id: "food3", category: "steaks" }
    ];
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App foodMenu={foodMenu} />, rootElement);

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"/>








    share|improve this answer


























    • Great answer! I posted something I found today that worked as well. Thanks!

      – Justin C.
      Nov 30 '18 at 2:41
















    1














    Based on previous answer I decided to make a real working solution of that. I also added another way of doing this with the forEach method. Please do run the snippet to see the results.



    Cheers!






    const Food = props => {
    //Do something that make sense with this :)
    const { food, addToCart, className } = props;
    return (
    <React.Fragment>
    Food: {food.id} <br />
    </React.Fragment>
    );
    };

    const App = props => {
    const categories = {
    Appetizers: "appetizers",
    Soupsalad: "soupsalad",
    Steaks: "steaks"
    };

    var menus1 = ;
    Object.keys(categories).forEach(categorie => {
    var subMenus = props.foodMenu
    .filter(food => food.category === categories[categorie])
    .map((food,i) => (
    <div key={i}>
    <h3>{categorie}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    menus1 = [...menus1, subMenus];
    });

    const menus2 = Object.entries(categories).map(e => {
    return props.foodMenu
    .filter(food => food.category === e[1])
    .map((food,i) => (
    <div key={i}>
    <h3>{e[0]}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    });

    return (
    <React.Fragment>
    <h2>Food Menu1 with foreach</h2>
    {menus1}

    <h2>Food Menu2 with map of map</h2>
    {menus2}
    </React.Fragment>
    );
    };


    var foodMenu = [
    { id: "food1", category: "appetizers" },
    { id: "food2", category: "soupsalad" },
    { id: "food3", category: "steaks" }
    ];
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App foodMenu={foodMenu} />, rootElement);

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"/>








    share|improve this answer


























    • Great answer! I posted something I found today that worked as well. Thanks!

      – Justin C.
      Nov 30 '18 at 2:41














    1












    1








    1







    Based on previous answer I decided to make a real working solution of that. I also added another way of doing this with the forEach method. Please do run the snippet to see the results.



    Cheers!






    const Food = props => {
    //Do something that make sense with this :)
    const { food, addToCart, className } = props;
    return (
    <React.Fragment>
    Food: {food.id} <br />
    </React.Fragment>
    );
    };

    const App = props => {
    const categories = {
    Appetizers: "appetizers",
    Soupsalad: "soupsalad",
    Steaks: "steaks"
    };

    var menus1 = ;
    Object.keys(categories).forEach(categorie => {
    var subMenus = props.foodMenu
    .filter(food => food.category === categories[categorie])
    .map((food,i) => (
    <div key={i}>
    <h3>{categorie}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    menus1 = [...menus1, subMenus];
    });

    const menus2 = Object.entries(categories).map(e => {
    return props.foodMenu
    .filter(food => food.category === e[1])
    .map((food,i) => (
    <div key={i}>
    <h3>{e[0]}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    });

    return (
    <React.Fragment>
    <h2>Food Menu1 with foreach</h2>
    {menus1}

    <h2>Food Menu2 with map of map</h2>
    {menus2}
    </React.Fragment>
    );
    };


    var foodMenu = [
    { id: "food1", category: "appetizers" },
    { id: "food2", category: "soupsalad" },
    { id: "food3", category: "steaks" }
    ];
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App foodMenu={foodMenu} />, rootElement);

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"/>








    share|improve this answer















    Based on previous answer I decided to make a real working solution of that. I also added another way of doing this with the forEach method. Please do run the snippet to see the results.



    Cheers!






    const Food = props => {
    //Do something that make sense with this :)
    const { food, addToCart, className } = props;
    return (
    <React.Fragment>
    Food: {food.id} <br />
    </React.Fragment>
    );
    };

    const App = props => {
    const categories = {
    Appetizers: "appetizers",
    Soupsalad: "soupsalad",
    Steaks: "steaks"
    };

    var menus1 = ;
    Object.keys(categories).forEach(categorie => {
    var subMenus = props.foodMenu
    .filter(food => food.category === categories[categorie])
    .map((food,i) => (
    <div key={i}>
    <h3>{categorie}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    menus1 = [...menus1, subMenus];
    });

    const menus2 = Object.entries(categories).map(e => {
    return props.foodMenu
    .filter(food => food.category === e[1])
    .map((food,i) => (
    <div key={i}>
    <h3>{e[0]}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    });

    return (
    <React.Fragment>
    <h2>Food Menu1 with foreach</h2>
    {menus1}

    <h2>Food Menu2 with map of map</h2>
    {menus2}
    </React.Fragment>
    );
    };


    var foodMenu = [
    { id: "food1", category: "appetizers" },
    { id: "food2", category: "soupsalad" },
    { id: "food3", category: "steaks" }
    ];
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App foodMenu={foodMenu} />, rootElement);

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"/>








    const Food = props => {
    //Do something that make sense with this :)
    const { food, addToCart, className } = props;
    return (
    <React.Fragment>
    Food: {food.id} <br />
    </React.Fragment>
    );
    };

    const App = props => {
    const categories = {
    Appetizers: "appetizers",
    Soupsalad: "soupsalad",
    Steaks: "steaks"
    };

    var menus1 = ;
    Object.keys(categories).forEach(categorie => {
    var subMenus = props.foodMenu
    .filter(food => food.category === categories[categorie])
    .map((food,i) => (
    <div key={i}>
    <h3>{categorie}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    menus1 = [...menus1, subMenus];
    });

    const menus2 = Object.entries(categories).map(e => {
    return props.foodMenu
    .filter(food => food.category === e[1])
    .map((food,i) => (
    <div key={i}>
    <h3>{e[0]}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    });

    return (
    <React.Fragment>
    <h2>Food Menu1 with foreach</h2>
    {menus1}

    <h2>Food Menu2 with map of map</h2>
    {menus2}
    </React.Fragment>
    );
    };


    var foodMenu = [
    { id: "food1", category: "appetizers" },
    { id: "food2", category: "soupsalad" },
    { id: "food3", category: "steaks" }
    ];
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App foodMenu={foodMenu} />, rootElement);

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"/>





    const Food = props => {
    //Do something that make sense with this :)
    const { food, addToCart, className } = props;
    return (
    <React.Fragment>
    Food: {food.id} <br />
    </React.Fragment>
    );
    };

    const App = props => {
    const categories = {
    Appetizers: "appetizers",
    Soupsalad: "soupsalad",
    Steaks: "steaks"
    };

    var menus1 = ;
    Object.keys(categories).forEach(categorie => {
    var subMenus = props.foodMenu
    .filter(food => food.category === categories[categorie])
    .map((food,i) => (
    <div key={i}>
    <h3>{categorie}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    menus1 = [...menus1, subMenus];
    });

    const menus2 = Object.entries(categories).map(e => {
    return props.foodMenu
    .filter(food => food.category === e[1])
    .map((food,i) => (
    <div key={i}>
    <h3>{e[0]}</h3>
    <div className="container">
    <Food
    className="food-menu"
    key={food.id}
    food={food}
    addToCart={""}
    />
    </div>
    </div>
    ));
    });

    return (
    <React.Fragment>
    <h2>Food Menu1 with foreach</h2>
    {menus1}

    <h2>Food Menu2 with map of map</h2>
    {menus2}
    </React.Fragment>
    );
    };


    var foodMenu = [
    { id: "food1", category: "appetizers" },
    { id: "food2", category: "soupsalad" },
    { id: "food3", category: "steaks" }
    ];
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App foodMenu={foodMenu} />, rootElement);

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"/>






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 30 '18 at 0:00

























    answered Nov 29 '18 at 23:54









    geostackgeostack

    264




    264













    • Great answer! I posted something I found today that worked as well. Thanks!

      – Justin C.
      Nov 30 '18 at 2:41



















    • Great answer! I posted something I found today that worked as well. Thanks!

      – Justin C.
      Nov 30 '18 at 2:41

















    Great answer! I posted something I found today that worked as well. Thanks!

    – Justin C.
    Nov 30 '18 at 2:41





    Great answer! I posted something I found today that worked as well. Thanks!

    – Justin C.
    Nov 30 '18 at 2:41













    1














    @geostack posted a great answer. Here is also something I found worked for my application.



    const sortByCategory = (dataArray) => {
    let sortedByCategory = {}
    dataArray.forEach(item => {
    if (sortedByCategory[item.category]) {
    sortedByCategory[item.category].push(item)
    } else {
    sortedByCategory[item.category] =
    sortedByCategory[item.category].push(item)
    }
    })
    return sortedByCategory
    }

    render(){
    let sortedData = sortByCategory(this.props.foodMenu)
    let foodMenu =

    for(let key in sortedData) {
    foodMenu.push(
    <div >
    <h3>{key.toUpperCase()}</h3>
    <br />
    <div>
    {
    sortedData[key].map(food => {
    return (
    <div key={food.id}>
    <Food key={food.id} food={food} addToCart={this.addToCart}/>
    <hr />
    </div>
    )
    })
    }
    </div>
    </div>
    )
    }

    return (
    <div>
    {foodMenu}
    </div>
    )
    }





    share|improve this answer




























      1














      @geostack posted a great answer. Here is also something I found worked for my application.



      const sortByCategory = (dataArray) => {
      let sortedByCategory = {}
      dataArray.forEach(item => {
      if (sortedByCategory[item.category]) {
      sortedByCategory[item.category].push(item)
      } else {
      sortedByCategory[item.category] =
      sortedByCategory[item.category].push(item)
      }
      })
      return sortedByCategory
      }

      render(){
      let sortedData = sortByCategory(this.props.foodMenu)
      let foodMenu =

      for(let key in sortedData) {
      foodMenu.push(
      <div >
      <h3>{key.toUpperCase()}</h3>
      <br />
      <div>
      {
      sortedData[key].map(food => {
      return (
      <div key={food.id}>
      <Food key={food.id} food={food} addToCart={this.addToCart}/>
      <hr />
      </div>
      )
      })
      }
      </div>
      </div>
      )
      }

      return (
      <div>
      {foodMenu}
      </div>
      )
      }





      share|improve this answer


























        1












        1








        1







        @geostack posted a great answer. Here is also something I found worked for my application.



        const sortByCategory = (dataArray) => {
        let sortedByCategory = {}
        dataArray.forEach(item => {
        if (sortedByCategory[item.category]) {
        sortedByCategory[item.category].push(item)
        } else {
        sortedByCategory[item.category] =
        sortedByCategory[item.category].push(item)
        }
        })
        return sortedByCategory
        }

        render(){
        let sortedData = sortByCategory(this.props.foodMenu)
        let foodMenu =

        for(let key in sortedData) {
        foodMenu.push(
        <div >
        <h3>{key.toUpperCase()}</h3>
        <br />
        <div>
        {
        sortedData[key].map(food => {
        return (
        <div key={food.id}>
        <Food key={food.id} food={food} addToCart={this.addToCart}/>
        <hr />
        </div>
        )
        })
        }
        </div>
        </div>
        )
        }

        return (
        <div>
        {foodMenu}
        </div>
        )
        }





        share|improve this answer













        @geostack posted a great answer. Here is also something I found worked for my application.



        const sortByCategory = (dataArray) => {
        let sortedByCategory = {}
        dataArray.forEach(item => {
        if (sortedByCategory[item.category]) {
        sortedByCategory[item.category].push(item)
        } else {
        sortedByCategory[item.category] =
        sortedByCategory[item.category].push(item)
        }
        })
        return sortedByCategory
        }

        render(){
        let sortedData = sortByCategory(this.props.foodMenu)
        let foodMenu =

        for(let key in sortedData) {
        foodMenu.push(
        <div >
        <h3>{key.toUpperCase()}</h3>
        <br />
        <div>
        {
        sortedData[key].map(food => {
        return (
        <div key={food.id}>
        <Food key={food.id} food={food} addToCart={this.addToCart}/>
        <hr />
        </div>
        )
        })
        }
        </div>
        </div>
        )
        }

        return (
        <div>
        {foodMenu}
        </div>
        )
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 30 '18 at 2:41









        Justin C.Justin C.

        475




        475






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53529500%2fdry-er-way-of-displaying-items-from-an-array-with-subcategories%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Contact image not getting when fetch all contact list from iPhone by CNContact

            count number of partitions of a set with n elements into k subsets

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks