嵌套对象总数

时间:2019-10-07 06:59:49

标签: javascript arrays reactjs object

我正在构建一个React应用,并且具有以下列表:

export const list = [
  {
    id: '1',
    group: 'sports 1',
    sports: [{
      'basketball': [
        {competed: true},
        {won: false}
      ],
      'soccer': [
        {competed: false},
        {won: false}
      ],
      'hockey': [
        {competed: false},
        {won: false}
      ]
    }],
    competedInAll: false
  },
  {
    id: '2',
    group: 'sports 2',
    sports: [{
      'tennis': [
        {competed: true},
        {won: false}
      ],
      'swimming': [
        {competed: true},
        {won: false}
      ],
      'baseball': [
        {competed: false},
        {won: false}
      ]
    }],
    competedInAll: false
  },
  {
    id: '3',
    group: 'sports 3',
    sports: [{
      'volleyball': [
        {competed: true},
        {won: false}
      ],
      'karate': [
        {competed: true},
        {won: false}
      ],
      'surfing': [
        {competed: true},
        {won: false}
      ]
    }],
    competedInAll: false
  }
];

此列表通过React挂钩置于状态:

const [list3, updateList3] = useState(list);

然后我像这样遍历列表:

const doMagicHere = () => {};

const getStatus = (item) => {
    let length = Object.values(item.sports[0]).filter(x => !x[0].competed).length;
    return length === 0 ? 'competed in all sports' : length + " remaining"
};

<ul>
    {list3.map(item => (
    <li key={item.id}>
        {item.group} ({getStatus(item)})
        <ul>
            {Object.keys(item.sports[0]).map((sport, i) => <li key={i} onClick={() => doMagicHere()}>{sport}</li>)}
        </ul>
    </li>
    ))}
</ul>

这将创建:

        
  •         运动1(剩余2个)         
                  
    • 篮球
    •             
    • 足球
    •             
    • 曲棍球
    •         
        
  •     
  •         运动2(剩余1个)         
                  
    • 网球
    •             
    • 游泳
    •             
    • 棒球
    •         
        
  •     
  •         运动3(参加所有运动)         
                  
    • 排球
    •             
    • 空手道
    •             
    • 冲浪
    •         
        
  1. 我如何添加onClick事件,以便在选择一个项目(设置为true)时减少总数,这将使文本读取“剩余2个”,然后读取“剩余1个”,以及最终为该组“参加所有运动”

1 个答案:

答案 0 :(得分:0)

export const list = [
  {
    id: '1',
    group: 'sports 1',
    sports: [{
      'basketball': [
        {competed: true},
        {won: false}
      ],
      'soccer': [
        {competed: false},
        {won: false}
      ],
      'hockey': [
        {competed: false},
        {won: false}
      ]
    }],
    competedInAll: false
  },
  {
    id: '2',
    group: 'sports 2',
    sports: [{
      'tennis': [
        {competed: true},
        {won: false}
      ],
      'swimming': [
        {competed: true},
        {won: false}
      ],
      'baseball': [
        {competed: false},
        {won: false}
      ]
    }],
    competedInAll: false
  },
  {
    id: '3',
    group: 'sports 3',
    sports: [{
      'volleyball': [
        {competed: true},
        {won: false}
      ],
      'karate': [
        {competed: true},
        {won: false}
      ],
      'surfing': [
        {competed: true},
        {won: false}
      ]
    }],
    competedInAll: false
  }
];

//I would suggest converting the list to a more manageable structure before adding it to the react state so that the doMagicHere() is simple

const parseList = list => {
 return list.reduce((acc,item) => {
 acc[item.group] = {
  id: item.id;
  sports: Object.entries(item.sports).reduce((a,[sport,value]) => {
   a[sport] = value.reduce((x,i) => { x = {...x,...i}; return x;},{});
   return a;
  },{})
 }
 return acc;
 },{})
}
const [sportsList, setSportsList] = useState(parseList(list));

//now sportsList is a more manageable structure

const getStatus = (item) => {
    let length = Object.values(item).filter(x => !x.competed).length;
    return length === 0 ? 'competed in all sports' : length + " remaining"
};

const doMagicHere = (group,sport) => {
   setSportsList({...sportsList,sports:{...sports,sports[sport]:{...sports[sport],competed:true}}});
 }
}

<ul>
    {Object.entries(sportsList).map([group, details] => (
    <li key={details.id}>
        {group} ({getStatus(details.sports)})
        <ul>
            {Object.keys(details.sports).map((sport, i) => <li key={i} onClick={() => doMagicHere(group,sport)}>{sport}</li>)}
        </ul>
    </li>
    ))}
</ul>