将对象数组过滤为新数组

时间:2019-05-02 00:56:08

标签: javascript arrays reactjs filter

在React中,我有:

    state = {
     Producers: [], 
     France: [],
     Spain: [],
     Germany: [],
     Portugal: [],
     Greece: [],
     Austria: [],
     isLoading: false
     };

生产者数组:

     {
    "_id" : ObjectId("5cc0bf1815cc7a2225edab0b"),
    "Code" : "FPG-BCH14",
    "URL" : "/jSQcl",
    "Just_In" : "",
    "Country" : "France",
    "Region" : "Burgundy"
},
{
    "_id" : ObjectId("5cc0bf1815cc7a2225edab0c"),
    "Code" : "FPG-CHA17",
    "URL" : "/XPxx",
    "Just_In" : "",
    "Country" : "France",
    "Region" : "Burgundy"  
},
{
    "_id" : ObjectId("5cc0bf1815cc7a2225edab0d"),
    "Code" : "FPG-BPN16",
    "Just_In" : "",
    "Country" : "France",
    "Region" : "Burgundy"

},

{
    "_id" : ObjectId("5cc0bf1815cc7a2225edab0e"),
    "Code" : "PAP-VIN17",
    "Country" : "Portugal",
    "Region" : "Vinho Verde",
    "Subregion" : "Lima"

}

现在我在state.Producers中拥有所有对象,并且想要放置任何具有值state.Producers.Country === "France"的对象(对于所有国家/地区,依此类推)。

这是我设置状态的方式:

    loadProducers = () => {

     API.getProducers()
     .then(res => 
     this.setState({Producers: res.data})
     )
     .catch(err => console.log(err));
       }

所以我想在为生产者设置状态后再为每个国家.then设置状态后还需要另外一个.filter语句,但是我似乎无法使其正常工作。

3 个答案:

答案 0 :(得分:-1)

假设您res.data具有[{Country: string}, {Country: string}...]的结构,则可以创建一个updatedState对象并将其放入其中。

类似这样的东西:

const loadProducers = () => {
    API.getProducers()
    .then(res => {
        const updatedState = {
            Producers: [], 
            France: [],
            Spain: [],
            Germany: [],
            Portugal: [],
            Greece: [],
            Austria: []
        };
        res.data.forEach((item) => {
            updatedState[item.Country].push(item);
        })
        // This line if you also need everything inside Producers
        updatedState.Producers = res.data;

        this.setState(updatedState);
    })
    .catch(err => console.log(err));
}

答案 1 :(得分:-1)

您可以这样做。

loadProducers = () => {
 API.getProducers()
  .then(({ data }) =>
    // Here we reduce all the results with respect to the country associated with
    updatedState = data.reduce((res, obj) => {
     if (!res[obj.Country]) {
       res[obj.Country] = [];
     }
     return { ...res, [obj.Country]: [...res[obj.Country], obj] }
    }, {});

    // Push all the data into Producers provided that you need it here. else you can ignore this line :)
    updatedState.Producers = data;

    //Finally update the state 
    this.setState(updatedState);
  ).catch(({ response }) => console.log(response));
}

希望这会有所帮助。

答案 2 :(得分:-1)

React.Component#setState()不返回任何内容,因此Promise#then()将有未定义的传递给它的回调。为避免这种情况,请传递a callback to setState(),使其在状态更新but you should use the proper method and use the life cycle React.Component#componentDidUpdate()之后运行。您应该使用生命周期的原因有很多,包括使您可以轻松更改数据源的来源而无需更改状态的自身生成方式,生命周期几乎不需要维护,并且在维护数据源时始终可以运行。组件已更新,这意味着您不会出现基于竞速异步条件的计时问题。

this.componentDidUpdate = function componentDidUpdate(
  previousProps,
  previousState
) {
  // wrap it in a comparison so that you don't infinitely loop
  if (//compare producers to previous producers here) {
    // they have changed, update state, use updater to prevent timing problems
    this.setState(state => {
      // keep changing data in sync
      // this also allows you to fetch changing data over time
      const update = {...state};
      state.producers.forEach(producer => {
        // safely initialize
        update[producer.Country] = update[producer.Country] || [];
        if (!update[producer.country].find(producer) {
          // push onto
          update[producer.Country].push(producer);
        }
      });
      return update;
    })
  }
}

保证在类中以安全的方式在状态更新上运行,并使您的关注点(访存)和派生类(派生结构)分开且易于维护。