简体   繁体   English

将对象数组过滤为新数组

[英]Filter array of objects into new arrays

In React I have: 在React中,我有:

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

Producers Array: 生产者数组:

     {
    "_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"

}

Right now I have all objects in state.Producers and I want to put any object that has the value state.Producers.Country === "France" (and so on for all the countries). 现在,我所有对象都处于state.Producers并且我想放置任何具有值state.Producers.Country === "France" (对于所有国家/地区等等)。

This is how I'm setting state: 这是我设置状态的方式:

    loadProducers = () => {

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

so I was thinking I need another .then statement after setting state for producers and then .filter for each country, but I can't seem to get it to work. 所以我以为在为生产者设置状态之后为每个国家设置.filter之后需要另一个.then语句,但是我似乎无法使其正常工作。

Assuming you res.data has a structure of [{Country: string}, {Country: string}...] , you could create a updatedState object and push the items into it. 假设res.data具有[{Country: string}, {Country: string}...] ,则可以创建一个updatedState对象并将项目推入其中。

Something like this: 像这样:

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));
}

You can do it this way. 您可以这样进行。

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));
}

Hope this helps. 希望这可以帮助。

React.Component#setState() does not return anything so a Promise#then() will have an undefined passed to it's callback. React.Component#setState()不返回任何内容,因此Promise#then()将有未定义的传递给它的回调。 To avoid this, instead pass a callback to setState() so that it runs after the state update, but you should use the proper method and use the life cycle React.Component#componentDidUpdate() . 为了避免这种情况,可以将回调传递给setState()以便它在状态更新后运行, 但是您应该使用适当的方法并使用生命周期React.Component#componentDidUpdate() The are many reasons you should want to use the life cycle including so that you can change where your data source comes from easily without changing how the state derives itself, the life cycle will need little to no maintenance, and it will always operate when the component gets updated meaning you won't have timing issues based on racing asynchronous conditions. 您应该使用生命周期的原因有很多,包括使您可以轻松更改数据源的来源而无需更改状态的自身生成方式,生命周期几乎不需要维护,并且在维护数据源时始终可以运行。组件已更新,这意味着您不会因为竞速异步条件而出现计时问题。

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;
    })
  }
}

This is guaranteed to run on a state update in a safe manner in a class, and keep your concerns(fetch) and derivatives(derived structures) separate and easy to maintain. 保证可以在一个类中以安全的方式在状态更新上运行,并使您的关注点(获取)和派生类(派生的结构)保持分离并易于维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM