如何从球员列表中筛选出各位置唯一的最多11名球员?
解决方案:筛选位置唯一的球员(最多11名)
嗨,这个需求很常见,结合你用到的ES6、Lodash和React技术栈,我给你两种实用的实现方案:
方案一:纯ES6实现(无需额外依赖)
我们可以用Array.reduce()配合Set来追踪已经出现过的位置,同时收集符合条件的球员,一旦拿到11个不同位置的球员就提前终止遍历,效率很高。
修改你的render代码如下:
render() { const { players } = this.props; // 筛选出位置唯一的球员,最多11名 const uniquePositionPlayers = players.reduce((acc, player) => { // 如果当前位置未被记录,且还没收集够11个 if (!acc.seenPositions.has(player.primaryPositionNumber) && acc.result.length < 11) { acc.seenPositions.add(player.primaryPositionNumber); acc.result.push(player); } return acc; }, { result: [], seenPositions: new Set() }).result; // 渲染Chip组件 const playerPositions = uniquePositionPlayers.map(player => ( <Chip className="player" data-position={player.primaryPositionNumber} avatar={<Avatar alt={player.fullName} src={`${player.image}.png`}/>} label={player.fullName} key={player.playerId} /> )); return <div>{playerPositions}</div>; }
关键逻辑说明:
- 用
reduce的累加器acc维护两个状态:result存储最终的球员列表,seenPositions是一个Set(查询效率更高),用来记录已出现的位置 - 遍历每个球员时,先检查位置是否未被记录,同时当前结果数量还没到11,满足条件就加入结果并标记位置
- 最后直接取累加器里的
result就是我们需要的目标列表
方案二:用Lodash简化代码
如果你已经在项目里引入了Lodash,可以用_.uniqBy()先按位置去重(保留每个位置的第一个球员),再用slice(0,11)限制数量,代码会更简洁:
import _ from 'lodash'; render() { const { players } = this.props; // 先按位置去重,再取前11名 const uniquePositionPlayers = _.slice(_.uniqBy(players, 'primaryPositionNumber'), 0, 11); const playerPositions = uniquePositionPlayers.map(player => ( <Chip className="player" data-position={player.primaryPositionNumber} avatar={<Avatar alt={player.fullName} src={`${player.image}.png`}/>} label={player.fullName} key={player.playerId} /> )); return <div>{playerPositions}</div>; }
关键逻辑说明:
_.uniqBy(players, 'primaryPositionNumber')会返回一个每个primaryPositionNumber唯一的数组,自动保留每个位置第一次出现的球员- 再用
_.slice(0,11)截取前11个(如果去重后的数量超过11的话)
两种方案都能满足你的需求,纯ES6方案不需要额外依赖,Lodash方案代码更简洁,你可以根据项目情况选择~
内容的提问来源于stack exchange,提问作者Tom Rudge
相关产品推荐
相关产品推荐

