如何使我的数组过滤和映射更紧凑、重复性更少?
How can I make my filtering and mapping of arrays more compact and less repetitive?
所以我有一个对象数组,我根据设置的过滤选项映射和显示这些对象。
这是示例数组:
[ { "id": 1, "class": "Assault Infantry", "missions": 5, "shots": 28, "hits": 21, "kills": 22, "dead": true, }, { "id": 2, "class": "Field Medic", "missions": 5, "shots": 22, "hits": 17, "kills": 15, "dead": false, }, { "id": 3, "class": "Field Medic", "missions": 3, "shots": 15, "hits": 11, "kills": 8, "dead": true, }, { "id": 4, "class": "Skirmisher", "missions": 7, "shots": 38, "hits": 27, "kills": 25, "dead": false, }, { "id": 5, "class": "Phalanx", "missions": 2, "shots": 5, "hits": 3, "kills": 5, "dead": true, }, { "id": 6, "missions": 6, "shots": 50, "hits": 41, "kills": 31, "dead": false, }, { "id": 7, "class": "Rookie", "missions": 1, "shots": 2, "hits": 1, "kills": 1, "dead": true, },
然后我有 select 或 select 特定字段,并使用 state:
按所选值对数组进行排序
const [data, setData] = useState([]);
const [sortType, setSortType] = useState('kills');
<select onChange={(e) => setSortType(e.target.value)}>
<option value="kills">Kills</option>
<option value="shots">Shots</option>
<option value="missions">Missions</option>
<option value="accuracy">Accuracy</option>
</select>
下面有一个复选框,如果选中,则进一步过滤排序数组并删除特定实例:
const [isChecked, setIsChecked] = useState(false);
const handleOnChange = () => {
setIsChecked(!isChecked);
};
<input onChange={handleOnChange} type="checkbox" id="isDead" name="isDead" checked={isChecked} />
<label htmlFor="isDead">Hide Dead</label>
这是执行大部分排序和过滤的代码,目前它按预期工作,我很高兴它的工作方式:
useEffect(() => {
const sortArray = type => {
const types = {
mvps: 'mvps',
kills: 'kills',
shots: 'shots',
missions: 'missions',
};
const sortProperty = types[type];
if(sortType === "accuracy") {
if(isChecked) {
console.log(isChecked);
const sorted = data.filter((user) => user.dead !== true);
console.log(sorted);
setData(sorted);
filtered(sorted);
} else {
const sorted = [...soldiers].sort((a, b) => (b.hits / b.shots * 100) - (a.hits / a.shots * 100));
setData(sorted);
filtered(sorted);
}
} else {
if(isChecked) {
const sorted = data.filter((user) => user.dead !== true);
console.log(sorted);
setData(sorted);
filtered(sorted);
} else {
const sorted = [...soldiers].sort((a, b) => b[sortProperty] - a[sortProperty]);
setData(sorted);
filtered(sorted);
}
}
};
sortArray(sortType);
}, [sortType, isChecked]);
它基本上采用 selector 的值并根据 selected 的值的类型对数组进行排序,如果“isDead”复选框它检查它过滤数组和删除将“dead”设置为 true 的实例。
但是,我的问题是我不断重复代码,我想添加更多复选框以通过更多选项过滤数组,如果它们被选中,如果我想这样做,它当前的设置方式意味着我会用不同的值一遍又一遍地重复相同的代码。如果我想为过滤数组添加更多复选框选项,例如使用“class”值,如何使代码的可重复性降低?例如有多个复选框来显示“Field Medic”、“Assault Infantry”等
我认为这里的关键问题是您需要在 if
分支中声明 sorted
,这就是为什么您需要所有重复的 setData(sorted)
等
所以解决方案是让 sorted
在条件之外的范围内变得可用,但仍然应用条件。
有不同的可能方法。
(我的示例并未反映您的确切用例,但我想它们说明了想法,从那里开始会很容易。)
例如将条件提取到单独的函数中:
const getSorted = function( sortType, isChecked ){
if(sortType === "accuracy") {
// ...
return data.filter((user) => user.dead !== true);
} else {
// ...
}
};
useEffect(() => {
// ...
const sorted = getSorted( sortType, isChecked ); // <-- all the if-conditions are in here
setData( sorted );
filtered( sorted );
// ...
}
另一种方法是定义一个对象来指定 sortType
的某些属性,例如条件、修饰符...例如:
const sortTypesSpec = {
'accuracy': {
sortFunction: (a, b) => b[sortProperty] - a[sortProperty],
filterFunction: (user) => user.dead !== true,
// ... other properties ?
},
'default': {
// ...
}
};
useEffect(() => {
// ...
const sorted = isChecked
? data.filter( sortTypesSpec[ sortType ].filterFunction )
: [...soldiers].sort( sortTypesSpec[ sortType ].sortFunction );
setData( sorted );
filtered( sorted );
// ...
当然,您也可以将其提取到函数中。
所以我有一个对象数组,我根据设置的过滤选项映射和显示这些对象。
这是示例数组:
[ { "id": 1, "class": "Assault Infantry", "missions": 5, "shots": 28, "hits": 21, "kills": 22, "dead": true, }, { "id": 2, "class": "Field Medic", "missions": 5, "shots": 22, "hits": 17, "kills": 15, "dead": false, }, { "id": 3, "class": "Field Medic", "missions": 3, "shots": 15, "hits": 11, "kills": 8, "dead": true, }, { "id": 4, "class": "Skirmisher", "missions": 7, "shots": 38, "hits": 27, "kills": 25, "dead": false, }, { "id": 5, "class": "Phalanx", "missions": 2, "shots": 5, "hits": 3, "kills": 5, "dead": true, }, { "id": 6, "missions": 6, "shots": 50, "hits": 41, "kills": 31, "dead": false, }, { "id": 7, "class": "Rookie", "missions": 1, "shots": 2, "hits": 1, "kills": 1, "dead": true, },
然后我有 select 或 select 特定字段,并使用 state:
按所选值对数组进行排序const [data, setData] = useState([]);
const [sortType, setSortType] = useState('kills');
<select onChange={(e) => setSortType(e.target.value)}>
<option value="kills">Kills</option>
<option value="shots">Shots</option>
<option value="missions">Missions</option>
<option value="accuracy">Accuracy</option>
</select>
下面有一个复选框,如果选中,则进一步过滤排序数组并删除特定实例:
const [isChecked, setIsChecked] = useState(false);
const handleOnChange = () => {
setIsChecked(!isChecked);
};
<input onChange={handleOnChange} type="checkbox" id="isDead" name="isDead" checked={isChecked} />
<label htmlFor="isDead">Hide Dead</label>
这是执行大部分排序和过滤的代码,目前它按预期工作,我很高兴它的工作方式:
useEffect(() => {
const sortArray = type => {
const types = {
mvps: 'mvps',
kills: 'kills',
shots: 'shots',
missions: 'missions',
};
const sortProperty = types[type];
if(sortType === "accuracy") {
if(isChecked) {
console.log(isChecked);
const sorted = data.filter((user) => user.dead !== true);
console.log(sorted);
setData(sorted);
filtered(sorted);
} else {
const sorted = [...soldiers].sort((a, b) => (b.hits / b.shots * 100) - (a.hits / a.shots * 100));
setData(sorted);
filtered(sorted);
}
} else {
if(isChecked) {
const sorted = data.filter((user) => user.dead !== true);
console.log(sorted);
setData(sorted);
filtered(sorted);
} else {
const sorted = [...soldiers].sort((a, b) => b[sortProperty] - a[sortProperty]);
setData(sorted);
filtered(sorted);
}
}
};
sortArray(sortType);
}, [sortType, isChecked]);
它基本上采用 selector 的值并根据 selected 的值的类型对数组进行排序,如果“isDead”复选框它检查它过滤数组和删除将“dead”设置为 true 的实例。 但是,我的问题是我不断重复代码,我想添加更多复选框以通过更多选项过滤数组,如果它们被选中,如果我想这样做,它当前的设置方式意味着我会用不同的值一遍又一遍地重复相同的代码。如果我想为过滤数组添加更多复选框选项,例如使用“class”值,如何使代码的可重复性降低?例如有多个复选框来显示“Field Medic”、“Assault Infantry”等
我认为这里的关键问题是您需要在 if
分支中声明 sorted
,这就是为什么您需要所有重复的 setData(sorted)
等
所以解决方案是让 sorted
在条件之外的范围内变得可用,但仍然应用条件。
有不同的可能方法。
(我的示例并未反映您的确切用例,但我想它们说明了想法,从那里开始会很容易。)
例如将条件提取到单独的函数中:
const getSorted = function( sortType, isChecked ){
if(sortType === "accuracy") {
// ...
return data.filter((user) => user.dead !== true);
} else {
// ...
}
};
useEffect(() => {
// ...
const sorted = getSorted( sortType, isChecked ); // <-- all the if-conditions are in here
setData( sorted );
filtered( sorted );
// ...
}
另一种方法是定义一个对象来指定 sortType
的某些属性,例如条件、修饰符...例如:
const sortTypesSpec = {
'accuracy': {
sortFunction: (a, b) => b[sortProperty] - a[sortProperty],
filterFunction: (user) => user.dead !== true,
// ... other properties ?
},
'default': {
// ...
}
};
useEffect(() => {
// ...
const sorted = isChecked
? data.filter( sortTypesSpec[ sortType ].filterFunction )
: [...soldiers].sort( sortTypesSpec[ sortType ].sortFunction );
setData( sorted );
filtered( sorted );
// ...
当然,您也可以将其提取到函数中。