React-Redux:根据状态是否匹配其他数组,从状态过滤对象数组

时间:2017-12-07 13:50:40

标签: javascript reactjs ecmascript-6 redux react-redux

我有一个连接的React组件,它从状态获取一个Plot对象数组。

它还从状态获取了几个字符串数组。像这样:

function mapStateToProps(state) {
    return {
        plots: state.plots.plots,
        varietyFilter: state.plots.varietyFilter,
        regionFilter: state.plots.regionFilter,
        growerFilter: state.plots.growerFilter,
        plotNameFilter: state.plots.plotNameFilter
    };
}

每个情节看起来像这样:

{ name, variety, region, grower}

...每个属性都是一个字符串。

我想通过适当的属性是否在这些过滤器数组中来过滤图。

标准解决方案是使用类似

的内容
const filteredArray = inputArray.filter( a => filterArray.indexOf(a.property)

这种方法有三个问题。首先,如果过滤器数组为空,则过滤后的数组的元素不会通过,而我希望它们全部通过。第二,当那些从状态显示的过滤器阵列尚未初始化时会发生什么?由于indexOf不可用,因此会出现错误。第三,我想链接这些过滤方法,但只链接那些初始化了某种过滤器数组的方法。

到目前为止,我已经提出了这个问题:

if (this.props.plots) {
            filteredProps = this.props.plots.filter(function(plot) {
                if (!varietyFilter.indexOf) {
                    return true;
                }
                return varietyFilter.indexOf(plot.variety) > -1;
            });
        }
但是,这似乎只是通过了一切。如果我删除第一个return语句,我会收到一个错误 - 当组件首次初始化时,indexOf方法不存在。

所以,两个问题。首先,如何过滤一个对象数组,以确定每个对象的给定属性是否包含在状态中可能存在或不存在的字符串数组中?其次,我如何为一系列数组执行此操作,每个数组对应于原始数组中对象的不同属性?

1 个答案:

答案 0 :(得分:1)

如果filterArray是一个空数组,则传递所有元素,如果它为null或未定义,则为了防止错误,你可以这样做:

const filteredArray = inputArray.filter( a => (filterArray || []).length === 0 || filterArray.includes(a.property));

下面的代码将空数组设置为filterArray的默认值,以防它为null或未定义:

filterArray || []

如果数组长度为正,则下面的部分进行过滤:

|| filterArray.includes(a.property)

这些代码等同于:

const filteredArray = inputArray.filter( a => {
    if (!filterArray) {
        filterArray = [];
    }
    if (filterArray.length === 0) {
        return true;
    } else {
        return filterArray.includes(a.property);
    }
}

链接多重过滤器可以通过以下方式完成:

var filters = [
    { prop: 'prop1', filterArray: ['abc', 'def'] },
    { prop: 'prop2', filterArray: ['abc'] },
    { prop: 'prop3', filterArray: ['abc', 'cde'] }
];

var filteredArray = [...inputArray];   // Copy inputArray

filters.forEach(filterObj => {
    filteredArray= filteredArray.filter( a => (filterObj.filterArray || []).length === 0 || filterObj.filterArray.includes(a[filterObj.prop]));
});