8-Bit Borges
8-Bit Borges

Reputation: 10033

Extract values from list of dictionaries and populate component

In my Class component, I have a list of 9 dictionaries as props:

[{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

Each dictionary key, value structure:

{name:'John', position:'fwd'}, {name:'Peter', position:'mid'}, {name:'Bill', position:'def'},...

Now I need to extract dictionary 'name' values and display them as text in my component.

For every group of three rows, the value must satisfy the condition of its unique 'position', that is, 3 names for 'fwd', then 3 names for 'mid', then names 3 for 'def', until the list is emptied.


This is the render:

  render() {
    const { players } = this.props;

    if(players){
        return (
         <div className="app">
            <div className="pos-wrapper">
              <div className="row">
                <Position>FWD Name 1</Position> 
                <Position>FWD Name 2</Position>
                <Position>FWD Name 3</Position> 
              </div>
              <div className="row">
                <Position>MID Name 1</Position> 
                <Position>MID Name 2</Position> 
                <Position>MID Name 3</Position> 
              </div>
                <div className="row">
                <Position>DEF Name 1</Position> 
                <Position>DEF Name 2</Position> 
                <Position>DEF Name 3</Position>
              </div>
            </div>
          </div>
        );
      }
      else{
        return null
        }
    }
}

Examples of expected result:

FWD NAME 1 -> John
...
...
MID NAME 1 -> Peter
...
...
DEF NAME 1 -> Bill
...
...

How do I extract the values using that condition and keeping the structure above?

Upvotes: 0

Views: 1373

Answers (3)

Nithish
Nithish

Reputation: 5999

I have used Array.reduce to convert the the data into groups according to the positions.

const App = (props) => {
  
const formatData = (data) => {
  const finalRes = data.reduce((res, {position, name}) => {
    if(res[position]) {
      res[position].push({position, name})
    } else {
      res[position] = [
        {position, name}
      ]
    }

    return res;
  },[]);
  return Object.values(finalRes);
}

  return formatData(props.data).map(d => {
    return d.map(obj => {
      return (
        <div key={`${obj.name}_${obj.position}`}>
          {obj.position.toUpperCase()} {obj.name}
        </div>
      )
    })
  })
}

const data = [
  { name: 'John 1', position: 'fwd' },
  { name: 'John 2', position: 'fwd' },
  { name: 'John 3', position: 'fwd' },
  { name: 'Peter 1', position: 'mid' },
  { name: 'Peter 2', position: 'mid' },
  { name: 'Peter 3', position: 'mid' },
  { name: 'Bill 1', position: 'def' },
  { name: 'Bill 2', position: 'def' },
  { name: 'Bill 3', position: 'def' }
];

ReactDOM.render(<App data={data}/>, document.getElementById("react"));
<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="react"></div>

Upvotes: 1

Bahroze Ali
Bahroze Ali

Reputation: 123

I guess this is how i would do it.

  render() {
    const { players } = this.props;

    if(players){
        return (
         <div className="app">
            <div className="pos-wrapper">
            {players.map((player,i)=>(
              <div key={i} className="row">
              {
                {
                  'fwd': <Position>FWD Name {player.name}</Position> ,
                  'mid': <Position>MID Name {player.name}</Position>,
                  'def': <Position>DEF Name {player.name}</Position> ,
                  
                }[player.position]
              }

              </div>
            ))}

            </div>
          </div>
        );
      }
      else{
        return null
        }
    }

Edited: It doesn't feel like it's an good idea but i guess following would give you the correct output

  render() {
    const { players } = this.props;

    if(players){
        return (
         <div className="app">
            <div className="pos-wrapper">
             <div className="row">
              {players.map((player,i)=>(
               {(player.position==="fwd")?
                  <Position key={i}>FWD Name {player.name}</Position>
               }
                   
              ))}

             </div>
             <div  className="row">
              {players.map((player,i)=>(
               {(player.position==="mid")?
                  <Position  key={i} >MID Name {player.name}</Position>
               }
                   
              ))}

            </div>
            <div  className="row">
              {players.map((player,i)=>(
               {(player.position==="def")?
                  <Position  key={i} >DEF Name {player.name}</Position>
               }
                   
              ))}

             </div>

            </div>
          </div>
        );
      }
      else{
        return null
        }
    }

Upvotes: 1

Matt
Matt

Reputation: 5428

Here's one example of how filter and map can work together:

function DisplayPlayers({players, position}) {
  return players.filter(player => player.position === position).map((player, index) => <div key={player.name}>{player.position.toUpperCase()} {player.name} {index+1}</div>);
}

function Application({players}) {
  return <div>
    <DisplayPlayers players={players} position="fwd" />
    <DisplayPlayers players={players} position="mid" />
    <DisplayPlayers players={players} position="def" />
  </div>;
}

ReactDOM.render(<Application players={[{name:'John', position:'fwd'},{name:'Jason', position:'fwd'}, {name:'Jones', position:'fwd'},{name:'Peter', position:'mid'}, {name:'Frank', position:'def'},{name:'Bill', position:'def'}]} />, document.getElementById('root'));
<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">
</div>

Upvotes: 0

Related Questions