【问题标题】:Smarter way of counting values in object (JS, React)计算对象中值的更智能方法(JS、React)
【发布时间】:2016-10-08 18:47:17
【问题描述】:

看看下面的代码,有没有更好的方法来获取在反应状态中包含某个键/值对的项目的数量?

一旦我正在经历的列表变大,这种方法似乎可能会导致瓶颈。

这是手头问题的简化示例:

class App extends React.Component {
  constructor() {
    super();
    
    this.state = {
      animals: [
        {type: 'cat'},
        {type: 'dog'},
        {type: 'cat'},
      ]
    };
  }

  render() {
    return(
      <div className="app">
        <Categories state={this.state} />
      </div>
    );
  }
}

class Categories extends React.Component {
  constructor() {
    super();

    this.countItems = this.countItems.bind(this);
  }

  countItems(type) {
    var count = 0;
  
    for(var i = 0; i < this.props.state.animals.length; i++) {
      if(this.props.state.animals[i].type === type) {
        count++;
      }
    }
    
    return count;
  }

  render() {
    return(
      <div className="categories">
        <div>Total animals: {this.props.state.animals.length}</div>
        <div>Cats: {this.countItems('cat')}</div>
        <div>Dogs: {this.countItems('dog')}</div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));
<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="container"></div>

【问题讨论】:

    标签: javascript arrays object reactjs


    【解决方案1】:

    如果这是您经常调用的方法,那么按类型索引您的数据(动物)并在您进行更改时保持更新可能会很有用。

    例如:

    App 构造函数中,您将创建另一个属性animalsPerType

      constructor() {
        super();
    
        this.state = {
          animals: [
            {type: 'cat'},
            {type: 'dog'},
            {type: 'cat'},
          ]
        };
        this.state.animalsPerType = this.state.animals.reduce(function(acc, animal) {
            return acc.set(animal.type, (acc.get(animal.type) || []).concat(animal));
        }, new Map());
      }
    

    那么你的countItems 方法就变得微不足道了:

      countItems(type) {
        return this.props.state.animalsPerType.get(type).length;
      }
    

    【讨论】:

      【解决方案2】:

      如果你不改变你的状态结构,那么你必须做一些循环并按类型计数。

      一种更具表现力的方法可能是使用 reduce:

      countItems(type) {  
          return this.props.state.animals.reduce((acc, next) => {
              return next.type == type ? acc + 1 : acc)
          }, 0);
        }
      

      但是,如果性能有问题:

      1. 您可以保持计数状态,每次animals更改时计算一次

      2. 您可以将每种类型的动物拆分为一个单独的数组,然后在每个数组上使用length

      3. 将您的状态更改为这样可能会有所帮助:

      this.state = { animals: { dogs: [], cats: [] } }

      【讨论】:

        猜你喜欢
        • 2010-12-04
        • 1970-01-01
        • 1970-01-01
        • 2017-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-18
        • 2022-01-25
        相关资源
        最近更新 更多