如何在反应中映射索引范围?
Posted
技术标签:
【中文标题】如何在反应中映射索引范围?【英文标题】:How to map an index range in react? 【发布时间】:2018-07-17 01:12:30 【问题描述】:<table>
<tbody>
this.state.data.map((person, i) => <TableRow key = i data = person />)
</tbody>
</table>
这会映射我的整个数组,但是我将如何从最小索引映射到最大索引?所以说我的数组有 500 个元素。我想将此数组(数据)从索引 15 映射到 24(含)。 (所以我的屏幕上只有 10 个元素)。
编辑:这些答案很有趣.. 但是没有提到 .filter() 吗?我看到它可能对我想要的有所帮助,但我正试图弄清楚如何在反应中做到这一点。
【问题讨论】:
【参考方案1】:使用Array#slice()
从this.state.data
中提取所需值的浅表副本。
const SubsetTable = props =>
let startIndex, endIndex, data = props
let subset = data.slice(startIndex, endIndex)
return (
<table>
<tbody>
subset.map((person, i) => (<TableRow key = i data = person />)
</tbody>
</table>
)
// Since splice() is inclusive of the range given, you'll need to
// adjust your range to include that last index if needed
// The below will grab all values in indexes 15-24,
<SubsetTable startIndex=15 endIndex=25 data=this.state.data />
由于您已更新您的问题,关于使用 Array#filter()
、filter()
需要您遍历整个集合。 Array#slice()
只会提取您想要提取的连续索引范围。 filter()
更好地满足您的条件,即您希望所有 Array 数据成员都满足并且您的集合是无序的。
【讨论】:
15 到 24 包括。请记住,Array.prototype.slice
上升到但不包括最后一个索引。 data.slice(startIndex, endIndex + 1)
:)【参考方案2】:
但是你设置了最小值/最大值(假设状态)
this.state =
min: 15,
max: 24,
;
如果索引 (i
) 大于或等于最小值,并且小于或等于最大值,您只需将映射调整为 if 语句即可返回。
this.state.data.map((person, i) =>
if (i >= this.state.min && i <= this.state.max)
return (<TableRow key = i data = person />);
)
现在,我们可以在这里说这是低效的。所以,在你达到最大值后,跳出循环,这可能需要不同的循环类型,因为我认为你不能从map
中跳出
【讨论】:
不确定它会影响什么,但此方法将返回在索引 24 处具有未定义值的数组。 @GiorgiMoniava 只是我自己输入的。很确定 React 会更喜欢这些值是null
。
@peteb 是的,我同意我不知道 react 对此有何反应。否则这也不是一个非常糟糕的解决方案。
@GiorgiMoniava 我什至没有想到这一点,我认为如果我们想要在这里提高效率,一个简单的for
循环将最有效,因为它会保留 O(n) 符号同时能够打破一旦达到最大值就退出。
@Sagivb.g 您不必返回它,在渲染中的 return 语句之前,您将 JSX 元素推送到变量中(例如在 for 循环中)然后渲染该变量。 (因为它的简单性,我会赞成这个答案;)虽然不确定未定义的值会如何影响事物:))。【参考方案3】:
这里的问题是Array.prototype.map
必须返回完全相同的数组长度。
所以你需要再次做一些过滤和映射。
为了尽量减少循环和迭代的数量,我会使用Array.prototype.reduce
,它可以让您在同一个迭代中进行过滤和映射。
运行示例:
const persons = [
value: 'John', id: 1 ,
value: 'Jane', id: 2 ,
value: 'Mike', id: 3 ,
value: 'Nikol', id: 4 ,
value: 'Bob', id: 5 ,
value: 'Dave', id: 6 ,
]
const TableRow = ( data ) => <tr><td>data.value</td></tr>
const start = 2;
const end = 4;
const App = () => (
<div >
<table>
<tbody>
persons.reduce((result, current, i) =>
if (i >= start && i <= end) // 0 based don't forget!
const row = (<TableRow key=i data=current />);
result.push(row);
return result;
, [])
</tbody>
</table>
</div>
);
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
【讨论】:
比较slice()
和reduce()
时的考虑;当您提取的范围较小时,对于较大的集合,reduce()
将比 slice()
慢。只获取需要的项目然后使用map()
迭代那个较小的集合更便宜。相反,reduce()
将始终需要遍历集合中的所有元素,即使该元素不在范围内。 reduce()
的性能提升是当您知道需要缩减整个项目集并对缩减集中的项目执行操作时。
与其他一些答案相比,滥用 reduce 来一次处理所有逻辑的可读性要低得多(并且不能证明更快,使用内联)。 push
ing 从减少中没有任何功能,那是一种可怕的气味。这只是另一个名称的 for 循环,而不是有意义的 reduce。以上是关于如何在反应中映射索引范围?的主要内容,如果未能解决你的问题,请参考以下文章