Clean way of close and reopen tag when variable change in React











up vote
1
down vote

favorite












I have an array like this:



[
{
group: "A",
id: "1",
name: "Mike"
},
{
group: "A",
id: "6",
name: "Sherley"
},
{
group: "B",
id: "3",
name: "Charlie"
},
{
group: "C",
id: "2",
name: "Dave"
}
]


and I want to group the array based on its group. The array is already sorted by group and name. So, I make something like this:



let lastgroup = c[0].group
return <Group title={lastgroup}>
{c.map(x => {
if (lastgroup == x.group) {
return <a href={"#" + x.id}>{x.name}</a>
} else {
lastgroup = x.group
return </Group><Group title={lastgroup}><a href={"#" + x.id}>{x.name}</a> //-> What should I put here for something like this?
}
})}
</Group>


Now, that solution above does not work obviously, and is not clean. How should I close and reopen Tag? Or is there a cleaner way to do that?



Thank you










share|improve this question


























    up vote
    1
    down vote

    favorite












    I have an array like this:



    [
    {
    group: "A",
    id: "1",
    name: "Mike"
    },
    {
    group: "A",
    id: "6",
    name: "Sherley"
    },
    {
    group: "B",
    id: "3",
    name: "Charlie"
    },
    {
    group: "C",
    id: "2",
    name: "Dave"
    }
    ]


    and I want to group the array based on its group. The array is already sorted by group and name. So, I make something like this:



    let lastgroup = c[0].group
    return <Group title={lastgroup}>
    {c.map(x => {
    if (lastgroup == x.group) {
    return <a href={"#" + x.id}>{x.name}</a>
    } else {
    lastgroup = x.group
    return </Group><Group title={lastgroup}><a href={"#" + x.id}>{x.name}</a> //-> What should I put here for something like this?
    }
    })}
    </Group>


    Now, that solution above does not work obviously, and is not clean. How should I close and reopen Tag? Or is there a cleaner way to do that?



    Thank you










    share|improve this question
























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I have an array like this:



      [
      {
      group: "A",
      id: "1",
      name: "Mike"
      },
      {
      group: "A",
      id: "6",
      name: "Sherley"
      },
      {
      group: "B",
      id: "3",
      name: "Charlie"
      },
      {
      group: "C",
      id: "2",
      name: "Dave"
      }
      ]


      and I want to group the array based on its group. The array is already sorted by group and name. So, I make something like this:



      let lastgroup = c[0].group
      return <Group title={lastgroup}>
      {c.map(x => {
      if (lastgroup == x.group) {
      return <a href={"#" + x.id}>{x.name}</a>
      } else {
      lastgroup = x.group
      return </Group><Group title={lastgroup}><a href={"#" + x.id}>{x.name}</a> //-> What should I put here for something like this?
      }
      })}
      </Group>


      Now, that solution above does not work obviously, and is not clean. How should I close and reopen Tag? Or is there a cleaner way to do that?



      Thank you










      share|improve this question













      I have an array like this:



      [
      {
      group: "A",
      id: "1",
      name: "Mike"
      },
      {
      group: "A",
      id: "6",
      name: "Sherley"
      },
      {
      group: "B",
      id: "3",
      name: "Charlie"
      },
      {
      group: "C",
      id: "2",
      name: "Dave"
      }
      ]


      and I want to group the array based on its group. The array is already sorted by group and name. So, I make something like this:



      let lastgroup = c[0].group
      return <Group title={lastgroup}>
      {c.map(x => {
      if (lastgroup == x.group) {
      return <a href={"#" + x.id}>{x.name}</a>
      } else {
      lastgroup = x.group
      return </Group><Group title={lastgroup}><a href={"#" + x.id}>{x.name}</a> //-> What should I put here for something like this?
      }
      })}
      </Group>


      Now, that solution above does not work obviously, and is not clean. How should I close and reopen Tag? Or is there a cleaner way to do that?



      Thank you







      javascript arrays typescript2.0






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 12 at 0:39









      Magician

      5473926




      5473926
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          To clean the implementation up, I would suggest an intermediate process that groups sub-arrays via Array#reduce(), followed by a mapping over the Object#entries() of the reduced result where you would "wrap" items with the <Group /> tags.



          The reduce step groups the data into an object, by the group key. Each grouping contains an array of items for that group (these items are JSX snippets "created" during the grouping stage).



          The second step is mapping over entries of that "reduced object". This allows you to wrap <Group/> tags around the group items collected for each group during the prior reduce step, without the need for the lastgroup idea:






          // Component state / data

          var data = [
          {
          group: "A",
          id: "1",
          name: "Mike"
          },
          {
          group: "A",
          id: "6",
          name: "Sherley"
          },
          {
          group: "B",
          id: "3",
          name: "Charlie"
          },
          {
          group: "C",
          id: "2",
          name: "Dave"
          }
          ]

          // Component render method

          render() {

          return Object.entries(data
          .reduce((grouping, item) => {

          // Insert items for group if not present
          if( !grouping[ item.group ] ) {
          grouping[ item.group ] = ;
          }

          var groupItems = grouping[ item.group ];

          // Create each group item, as we build up the items for this group
          groupItems.push(<a href={"#" + item.id}>{item.name}</a>);

          return grouping;

          }, {}))
          .map((entry) => {

          // entry[0] is the group key, entry[0] is the group value (item array)
          const group = entry[0];
          const items = entry[1];

          // Wrap items of each group with <Group/> tags
          return <Group title={group}>{ items }</Group>
          })

          }








          share|improve this answer























          • Thank you... This should work.
            – Magician
            Nov 12 at 17:35


















          up vote
          0
          down vote













          Step 1, group entries by attribute group.
          See How to group an array of objects by key for more information



          const groups = data.reduce((reducer, current) => {
          reducer[current.group] = reducer[current.group] ||
          reducer[current.group].push(current)
          return reducer
          }, {})
          /*
          console.log(groups)
          should give you
          { A:
          [ { group: 'A', id: '1', name: 'Mike' },
          { group: 'A', id: '6', name: 'Sherley' }
          ],
          B:
          [ { group: 'B', id: '3', name: 'Charlie' } ],
          C:
          [ { group: 'C', id: '2', name: 'Dave' } ]
          }
          */


          Step 2, render the groups



          const keys = Object.keys(groups)
          return (<div>
          {keys.map(key => {
          const currentGroup = groups[key]
          // now render entries inside each group
          return (<Group key={key} title={key}>
          {currentGroup.map(entry => {
          return <a key={entry.id} href={`#${entry.id}`}>{entry.name}</a>
          })}
          </Group>)
          })}
          </div>)





          share|improve this answer





















          • Actually, both method are the same. I accept the other because he answered first. Thank you
            – Magician
            Nov 12 at 17:35











          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',
          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%2f53254677%2fclean-way-of-close-and-reopen-tag-when-variable-change-in-react%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








          up vote
          0
          down vote



          accepted










          To clean the implementation up, I would suggest an intermediate process that groups sub-arrays via Array#reduce(), followed by a mapping over the Object#entries() of the reduced result where you would "wrap" items with the <Group /> tags.



          The reduce step groups the data into an object, by the group key. Each grouping contains an array of items for that group (these items are JSX snippets "created" during the grouping stage).



          The second step is mapping over entries of that "reduced object". This allows you to wrap <Group/> tags around the group items collected for each group during the prior reduce step, without the need for the lastgroup idea:






          // Component state / data

          var data = [
          {
          group: "A",
          id: "1",
          name: "Mike"
          },
          {
          group: "A",
          id: "6",
          name: "Sherley"
          },
          {
          group: "B",
          id: "3",
          name: "Charlie"
          },
          {
          group: "C",
          id: "2",
          name: "Dave"
          }
          ]

          // Component render method

          render() {

          return Object.entries(data
          .reduce((grouping, item) => {

          // Insert items for group if not present
          if( !grouping[ item.group ] ) {
          grouping[ item.group ] = ;
          }

          var groupItems = grouping[ item.group ];

          // Create each group item, as we build up the items for this group
          groupItems.push(<a href={"#" + item.id}>{item.name}</a>);

          return grouping;

          }, {}))
          .map((entry) => {

          // entry[0] is the group key, entry[0] is the group value (item array)
          const group = entry[0];
          const items = entry[1];

          // Wrap items of each group with <Group/> tags
          return <Group title={group}>{ items }</Group>
          })

          }








          share|improve this answer























          • Thank you... This should work.
            – Magician
            Nov 12 at 17:35















          up vote
          0
          down vote



          accepted










          To clean the implementation up, I would suggest an intermediate process that groups sub-arrays via Array#reduce(), followed by a mapping over the Object#entries() of the reduced result where you would "wrap" items with the <Group /> tags.



          The reduce step groups the data into an object, by the group key. Each grouping contains an array of items for that group (these items are JSX snippets "created" during the grouping stage).



          The second step is mapping over entries of that "reduced object". This allows you to wrap <Group/> tags around the group items collected for each group during the prior reduce step, without the need for the lastgroup idea:






          // Component state / data

          var data = [
          {
          group: "A",
          id: "1",
          name: "Mike"
          },
          {
          group: "A",
          id: "6",
          name: "Sherley"
          },
          {
          group: "B",
          id: "3",
          name: "Charlie"
          },
          {
          group: "C",
          id: "2",
          name: "Dave"
          }
          ]

          // Component render method

          render() {

          return Object.entries(data
          .reduce((grouping, item) => {

          // Insert items for group if not present
          if( !grouping[ item.group ] ) {
          grouping[ item.group ] = ;
          }

          var groupItems = grouping[ item.group ];

          // Create each group item, as we build up the items for this group
          groupItems.push(<a href={"#" + item.id}>{item.name}</a>);

          return grouping;

          }, {}))
          .map((entry) => {

          // entry[0] is the group key, entry[0] is the group value (item array)
          const group = entry[0];
          const items = entry[1];

          // Wrap items of each group with <Group/> tags
          return <Group title={group}>{ items }</Group>
          })

          }








          share|improve this answer























          • Thank you... This should work.
            – Magician
            Nov 12 at 17:35













          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          To clean the implementation up, I would suggest an intermediate process that groups sub-arrays via Array#reduce(), followed by a mapping over the Object#entries() of the reduced result where you would "wrap" items with the <Group /> tags.



          The reduce step groups the data into an object, by the group key. Each grouping contains an array of items for that group (these items are JSX snippets "created" during the grouping stage).



          The second step is mapping over entries of that "reduced object". This allows you to wrap <Group/> tags around the group items collected for each group during the prior reduce step, without the need for the lastgroup idea:






          // Component state / data

          var data = [
          {
          group: "A",
          id: "1",
          name: "Mike"
          },
          {
          group: "A",
          id: "6",
          name: "Sherley"
          },
          {
          group: "B",
          id: "3",
          name: "Charlie"
          },
          {
          group: "C",
          id: "2",
          name: "Dave"
          }
          ]

          // Component render method

          render() {

          return Object.entries(data
          .reduce((grouping, item) => {

          // Insert items for group if not present
          if( !grouping[ item.group ] ) {
          grouping[ item.group ] = ;
          }

          var groupItems = grouping[ item.group ];

          // Create each group item, as we build up the items for this group
          groupItems.push(<a href={"#" + item.id}>{item.name}</a>);

          return grouping;

          }, {}))
          .map((entry) => {

          // entry[0] is the group key, entry[0] is the group value (item array)
          const group = entry[0];
          const items = entry[1];

          // Wrap items of each group with <Group/> tags
          return <Group title={group}>{ items }</Group>
          })

          }








          share|improve this answer














          To clean the implementation up, I would suggest an intermediate process that groups sub-arrays via Array#reduce(), followed by a mapping over the Object#entries() of the reduced result where you would "wrap" items with the <Group /> tags.



          The reduce step groups the data into an object, by the group key. Each grouping contains an array of items for that group (these items are JSX snippets "created" during the grouping stage).



          The second step is mapping over entries of that "reduced object". This allows you to wrap <Group/> tags around the group items collected for each group during the prior reduce step, without the need for the lastgroup idea:






          // Component state / data

          var data = [
          {
          group: "A",
          id: "1",
          name: "Mike"
          },
          {
          group: "A",
          id: "6",
          name: "Sherley"
          },
          {
          group: "B",
          id: "3",
          name: "Charlie"
          },
          {
          group: "C",
          id: "2",
          name: "Dave"
          }
          ]

          // Component render method

          render() {

          return Object.entries(data
          .reduce((grouping, item) => {

          // Insert items for group if not present
          if( !grouping[ item.group ] ) {
          grouping[ item.group ] = ;
          }

          var groupItems = grouping[ item.group ];

          // Create each group item, as we build up the items for this group
          groupItems.push(<a href={"#" + item.id}>{item.name}</a>);

          return grouping;

          }, {}))
          .map((entry) => {

          // entry[0] is the group key, entry[0] is the group value (item array)
          const group = entry[0];
          const items = entry[1];

          // Wrap items of each group with <Group/> tags
          return <Group title={group}>{ items }</Group>
          })

          }








          // Component state / data

          var data = [
          {
          group: "A",
          id: "1",
          name: "Mike"
          },
          {
          group: "A",
          id: "6",
          name: "Sherley"
          },
          {
          group: "B",
          id: "3",
          name: "Charlie"
          },
          {
          group: "C",
          id: "2",
          name: "Dave"
          }
          ]

          // Component render method

          render() {

          return Object.entries(data
          .reduce((grouping, item) => {

          // Insert items for group if not present
          if( !grouping[ item.group ] ) {
          grouping[ item.group ] = ;
          }

          var groupItems = grouping[ item.group ];

          // Create each group item, as we build up the items for this group
          groupItems.push(<a href={"#" + item.id}>{item.name}</a>);

          return grouping;

          }, {}))
          .map((entry) => {

          // entry[0] is the group key, entry[0] is the group value (item array)
          const group = entry[0];
          const items = entry[1];

          // Wrap items of each group with <Group/> tags
          return <Group title={group}>{ items }</Group>
          })

          }





          // Component state / data

          var data = [
          {
          group: "A",
          id: "1",
          name: "Mike"
          },
          {
          group: "A",
          id: "6",
          name: "Sherley"
          },
          {
          group: "B",
          id: "3",
          name: "Charlie"
          },
          {
          group: "C",
          id: "2",
          name: "Dave"
          }
          ]

          // Component render method

          render() {

          return Object.entries(data
          .reduce((grouping, item) => {

          // Insert items for group if not present
          if( !grouping[ item.group ] ) {
          grouping[ item.group ] = ;
          }

          var groupItems = grouping[ item.group ];

          // Create each group item, as we build up the items for this group
          groupItems.push(<a href={"#" + item.id}>{item.name}</a>);

          return grouping;

          }, {}))
          .map((entry) => {

          // entry[0] is the group key, entry[0] is the group value (item array)
          const group = entry[0];
          const items = entry[1];

          // Wrap items of each group with <Group/> tags
          return <Group title={group}>{ items }</Group>
          })

          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 12 at 1:17

























          answered Nov 12 at 0:51









          Dacre Denny

          9,3084729




          9,3084729












          • Thank you... This should work.
            – Magician
            Nov 12 at 17:35


















          • Thank you... This should work.
            – Magician
            Nov 12 at 17:35
















          Thank you... This should work.
          – Magician
          Nov 12 at 17:35




          Thank you... This should work.
          – Magician
          Nov 12 at 17:35












          up vote
          0
          down vote













          Step 1, group entries by attribute group.
          See How to group an array of objects by key for more information



          const groups = data.reduce((reducer, current) => {
          reducer[current.group] = reducer[current.group] ||
          reducer[current.group].push(current)
          return reducer
          }, {})
          /*
          console.log(groups)
          should give you
          { A:
          [ { group: 'A', id: '1', name: 'Mike' },
          { group: 'A', id: '6', name: 'Sherley' }
          ],
          B:
          [ { group: 'B', id: '3', name: 'Charlie' } ],
          C:
          [ { group: 'C', id: '2', name: 'Dave' } ]
          }
          */


          Step 2, render the groups



          const keys = Object.keys(groups)
          return (<div>
          {keys.map(key => {
          const currentGroup = groups[key]
          // now render entries inside each group
          return (<Group key={key} title={key}>
          {currentGroup.map(entry => {
          return <a key={entry.id} href={`#${entry.id}`}>{entry.name}</a>
          })}
          </Group>)
          })}
          </div>)





          share|improve this answer





















          • Actually, both method are the same. I accept the other because he answered first. Thank you
            – Magician
            Nov 12 at 17:35















          up vote
          0
          down vote













          Step 1, group entries by attribute group.
          See How to group an array of objects by key for more information



          const groups = data.reduce((reducer, current) => {
          reducer[current.group] = reducer[current.group] ||
          reducer[current.group].push(current)
          return reducer
          }, {})
          /*
          console.log(groups)
          should give you
          { A:
          [ { group: 'A', id: '1', name: 'Mike' },
          { group: 'A', id: '6', name: 'Sherley' }
          ],
          B:
          [ { group: 'B', id: '3', name: 'Charlie' } ],
          C:
          [ { group: 'C', id: '2', name: 'Dave' } ]
          }
          */


          Step 2, render the groups



          const keys = Object.keys(groups)
          return (<div>
          {keys.map(key => {
          const currentGroup = groups[key]
          // now render entries inside each group
          return (<Group key={key} title={key}>
          {currentGroup.map(entry => {
          return <a key={entry.id} href={`#${entry.id}`}>{entry.name}</a>
          })}
          </Group>)
          })}
          </div>)





          share|improve this answer





















          • Actually, both method are the same. I accept the other because he answered first. Thank you
            – Magician
            Nov 12 at 17:35













          up vote
          0
          down vote










          up vote
          0
          down vote









          Step 1, group entries by attribute group.
          See How to group an array of objects by key for more information



          const groups = data.reduce((reducer, current) => {
          reducer[current.group] = reducer[current.group] ||
          reducer[current.group].push(current)
          return reducer
          }, {})
          /*
          console.log(groups)
          should give you
          { A:
          [ { group: 'A', id: '1', name: 'Mike' },
          { group: 'A', id: '6', name: 'Sherley' }
          ],
          B:
          [ { group: 'B', id: '3', name: 'Charlie' } ],
          C:
          [ { group: 'C', id: '2', name: 'Dave' } ]
          }
          */


          Step 2, render the groups



          const keys = Object.keys(groups)
          return (<div>
          {keys.map(key => {
          const currentGroup = groups[key]
          // now render entries inside each group
          return (<Group key={key} title={key}>
          {currentGroup.map(entry => {
          return <a key={entry.id} href={`#${entry.id}`}>{entry.name}</a>
          })}
          </Group>)
          })}
          </div>)





          share|improve this answer












          Step 1, group entries by attribute group.
          See How to group an array of objects by key for more information



          const groups = data.reduce((reducer, current) => {
          reducer[current.group] = reducer[current.group] ||
          reducer[current.group].push(current)
          return reducer
          }, {})
          /*
          console.log(groups)
          should give you
          { A:
          [ { group: 'A', id: '1', name: 'Mike' },
          { group: 'A', id: '6', name: 'Sherley' }
          ],
          B:
          [ { group: 'B', id: '3', name: 'Charlie' } ],
          C:
          [ { group: 'C', id: '2', name: 'Dave' } ]
          }
          */


          Step 2, render the groups



          const keys = Object.keys(groups)
          return (<div>
          {keys.map(key => {
          const currentGroup = groups[key]
          // now render entries inside each group
          return (<Group key={key} title={key}>
          {currentGroup.map(entry => {
          return <a key={entry.id} href={`#${entry.id}`}>{entry.name}</a>
          })}
          </Group>)
          })}
          </div>)






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 at 1:18









          Rico Chen

          67348




          67348












          • Actually, both method are the same. I accept the other because he answered first. Thank you
            – Magician
            Nov 12 at 17:35


















          • Actually, both method are the same. I accept the other because he answered first. Thank you
            – Magician
            Nov 12 at 17:35
















          Actually, both method are the same. I accept the other because he answered first. Thank you
          – Magician
          Nov 12 at 17:35




          Actually, both method are the same. I accept the other because he answered first. Thank you
          – Magician
          Nov 12 at 17:35


















          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.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • 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%2f53254677%2fclean-way-of-close-and-reopen-tag-when-variable-change-in-react%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

          Bressuire

          Vorschmack

          Quarantine