【问题标题】:Is it possible to map only a portion of an array? (Array.map())是否可以仅映射数组的一部分? (数组.map())
【发布时间】:2017-01-20 04:20:50
【问题描述】:

我正在构建一个使用 React.js 作为前端框架的项目。在一个特定页面上,我向用户显示了完整的数据集。我有一个包含这个完整数据集的数组。它是一个 JSON 对象数组。在向用户呈现这些数据方面,我目前通过使用 Array.map() 返回每个数据项来显示整个数据集。

这是朝着正确方向迈出的一步,但现在我只需要显示数据集的一部分,而不是全部内容,我还希望在了解总数据集的多少方面进行一些控制显示,以及有多少数据集尚未显示。基本上我正在构建类似“查看更多”按钮的东西,它可以向用户加载更多数据项。

这是我现在使用的,“feed”代表我的 JSON 对象数组。 (这会显示整个数据集。)

 return (
  <div className={feedClass}>
  {
    feed.map((item, index) => {
      return <FeedItem key={index} data={item}/>
    })
  }
  </div>
);

我想知道是否可以仅在数组的一部分上使用 .map() 而不必事先分解数组?我知道一个可能的解决方案是保存完整的数据集,并将其分成几个部分,然后 .map() 这些部分,但是有没有办法 .map() 数组的一部分而不必打破起来了吗?

感谢任何和所有反馈。谢谢!

【问题讨论】:

  • 我不使用 React,但是你不能在你想要的范围之间对数组进行切片或过滤,然后将其传递给 map 函数吗?
  • 使用filterslice 拆分它会丢失数组的其余部分。为什么不在map 中添加if 语句?

标签: javascript arrays json reactjs


【解决方案1】:

不要尝试在映射步骤中通过 hack 来解决此问题。

取而代之,slice() the list to the right length first 在映射之前:

class Feed extends React.Component {
  constructor(props) {
    super(props)
    
    this.handleShowMore = this.handleShowMore.bind(this)
    
    this.state = {
      items: ['Item A', 'Item B', 'Item C', 'Item D'],
      showItems: 2
    }
  }
  
  handleShowMore() {
    this.setState({
      showItems: 
        this.state.showItems >= this.state.items.length ?
          this.state.showItems : this.state.showItems + 1
    })
  }
  
  render() {
    const items = this.state.items.slice(0, this.state.showItems).map(
      (item) => <div>{item}</div>
    )
    
    return (
      <div>
        {items}
        <button onClick={this.handleShowMore}>
          Show more!
        </button>
      </div>
    )
  }
}
  
ReactDOM.render(
  <Feed />,
  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>

【讨论】:

  • 就用reduce吧,是更好的选择。
  • 我知道这个问题很老了,但我遇到了类似的问题。但就我而言,我遍历数据数组并用地图填充不同的表列。如果我点击“显示更多”,它会正确呈现新项目,但会从第一个呈现的项目中删除一列......我不明白为什么。
【解决方案2】:

你可以在映射数组之前使用slice 函数,看起来你想在那里做一些分页。

var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
var citrus = fruits.slice(1, 3);

// fruits contains ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
// citrus contains ['Orange','Lemon']

【讨论】:

    【解决方案3】:

    Array.reduce 应该满足您的要求。只需根据您想要的范围更改 if 语句即可。

    var excludeAfterIndex = 5;
    
    feed.reduce((mappedArray, item, index) => {
      if (index > excludeAfterIndex) { // Whatever range condition you want
        mappedArray.push(<FeedItem key={index} data={item}/>);
      }
    
      return mappedArray;
    }, []);
    

    【讨论】:

      【解决方案4】:

      我脑海中最简单的方法就是使用过滤器和地图

      const feed = [1,2,3,4,5,6,7,8,9,10,11]
      feed.filter((item, index) => index < 5).map((filteredItem) => //do somthing with filtred item here//)
      

      其中 5 只是您想要获得的物品数量

      【讨论】:

        【解决方案5】:

        如果你只想映射数组的一部分,你应该先 filter() 你的数组根据条件获得预期的部分:

        array.filter(item => <condition>).map();
        

        【讨论】:

        • 过滤但是使过滤后的值不可引用。因此reduce 是更好的选择。
        【解决方案6】:

        是的,您可以根据索引映射数组的一部分。例如:

        yourArray = yourArray.map(function (element, index, array) {
                if (array.indexOf(element) < yourIndex) {
                    return {
                       //logic here
                    };
                } else {
                    return {
                        //logic here
                    };
                }
        
            });
        

        【讨论】:

          【解决方案7】:

          Array#map 遍历所有项目。

          map() 方法创建一个新数组,其结果是对该数组中的每个元素调用提供的函数。

          你可以使用Array#filter

          filter() 方法创建一个新数组,其中包含所有通过所提供函数实现的测试的元素。

          为想要的项目,然后为想要的格式应用地图。

          【讨论】:

            【解决方案8】:

            没有任何版本的 map() 函数只映射数组的一部分。

            您可以将 .map() 与 .filter() 结合使用。

            您将当前元素的索引作为 map 的第二个参数,如果您有一个用于当前页面和页面大小的变量,您可以很容易地从数组中过滤出正确的页面,而无需真正切分它。

            var currentPage = 1;
            var pageSize = 25;
            
            dataArray.filter(function(elt, index) {
            
                var upperThreshold = currentPage * pageSize;
                var lowerThreshold = currentPage * pageSize - pageSize;
            
                return index < upperThreshold && index > lowerThreshold;
            
            });
            

            【讨论】:

              【解决方案9】:

              使用slice() 比在 map 或 reduce 函数中添加条件要好,但它仍然会为数组的该段创建一个额外的、未使用的副本。根据您正在做的事情,这可能是不希望的。相反,只需使用自定义地图功能:

              function sliceMap(fn, from, toExclusive, array) {
                const len = toExclusive - from;
                const mapped = Array(len);
              
                for (let i = 0; i < len; i++) {
                  mapped[i] = fn(array[i + from], i);
                }
              
                return mapped;
              };
              

              请注意,fn 接收数组值和(现在)从零开始的索引。您可能想要传递原始索引 (i + from)。您可能还想将完整的array 作为第三个参数传递,这就是Array.map 所做的。

              【讨论】:

                【解决方案10】:

                使用这个,简单的方法

                const [limit, setLimit] = useState(false);
                const data = [{name: "john}, {name: 'Anna'}]
                

                这里我们将有 2 个案例:

                1. 仅显示 John 的第一个数据
                2. 显示全部
                data.slice(0, extended ? data.length : 1).map((item, index) => <Text>{item.name}</Text>)
                

                ....

                【讨论】:

                  猜你喜欢
                  • 2011-05-14
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-12-21
                  • 1970-01-01
                  • 2012-03-16
                  • 1970-01-01
                  • 2020-12-05
                  • 1970-01-01
                  相关资源
                  最近更新 更多