Javascript 如何在reactjs中创建一个函数来按属性对对象数组进行排序?
我需要创建一个用于排序对象数组的函数。数组如下所示:Javascript 如何在reactjs中创建一个函数来按属性对对象数组进行排序?,javascript,reactjs,sorting,Javascript,Reactjs,Sorting,我需要创建一个用于排序对象数组的函数。数组如下所示: array=[ 0: {id: "7", name: "Aaaaa", level: "3/4", generation: "2", area: "JavaScript", …} 1: {id: "6", name: "Bbbbbb", level: "2/4", generation
array=[ 0: {id: "7", name: "Aaaaa", level: "3/4", generation: "2", area: "JavaScript", …} 1: {id: "6", name: "Bbbbbb", level: "2/4", generation: "2", area: "JavaScript", …} 2: {id: "10", name: "DEV #1", level: "1/1", generation: "1", area: "Development", …} ]
<span className="margin-h-10 row align-center padding-r-5 pointer"
onClick={() => {
this.setState({ asc: !this.state.asc });
this.props.sortHandle('name', this.state.asc)
}}>
<span className="margin-r-5">Name</span>
<FontAwesomeIcon
icon={this.state.asc ? 'chevron-up' : 'chevron-down'}
style={{ color: "#7f7f7f", fontSize: "10px" }}
/>
</span>
<span className="margin-h-10 row align-center padding-r-5 pointer"
onClick={() => {
this.setState({ asc: !this.state.asc });
this.props.sortHandle('date', this.state.asc)
}}>
<span className="margin-r-5">Date</span>
这就是i
调用函数的方式
sortHandle={() => this.sortArray("someProperty", "desc/asc")}
我已经设法使它的工作,但只有在我点击分拣机的第二次
sortCourses(sorter, asc) {
let courses = this.state.courses;
let sortedCourses = []
switch (sorter) {
case 'level':
sortedCourses.push(courses.sort((a, b) => { return (parseInt(a.level) - parseInt(b.level)) ? 1 : -1 }))
break;
case 'generation':
sortedCourses.push(courses.sort((a, b) => { return (parseInt(a.generation) - parseInt(b.generation)) ? 1 : -1 }))
break;
case 'name':
sortedCourses.push(courses.sort((a, b) => { return (a.name.toLowerCase() - b.name.toLowerCase()) ? 1 : -1 }))
case 'area':
sortedCourses.push(courses.sort((a, b) => { return (a.area.toLowerCase() - b.area.toLowerCase()) ? 1 : -1 }))
break;
case 'date':
sortedCourses.push(courses.sort((a, b) => { return (a.startDate - b.startDate) ? 1 : -1 }))
break;
}
this.setState({ courses: sortedCourses[0] }, () => { console.log(this.state.courses) })
if (asc) {
return sortedCourses[0]
}
else if (!asc) {
return sortedCourses[0].reverse()
}
}
我从props sortHandle获得sortProperty和asc/desc,它是子组件中的一个函数
sortHandle={(sorter,asc) => this.sortCourses(sorter,asc)}
在我的子组件中,排序器如下所示:
array=[ 0: {id: "7", name: "Aaaaa", level: "3/4", generation: "2", area: "JavaScript", …} 1: {id: "6", name: "Bbbbbb", level: "2/4", generation: "2", area: "JavaScript", …} 2: {id: "10", name: "DEV #1", level: "1/1", generation: "1", area: "Development", …} ]
<span className="margin-h-10 row align-center padding-r-5 pointer"
onClick={() => {
this.setState({ asc: !this.state.asc });
this.props.sortHandle('name', this.state.asc)
}}>
<span className="margin-r-5">Name</span>
<FontAwesomeIcon
icon={this.state.asc ? 'chevron-up' : 'chevron-down'}
style={{ color: "#7f7f7f", fontSize: "10px" }}
/>
</span>
<span className="margin-h-10 row align-center padding-r-5 pointer"
onClick={() => {
this.setState({ asc: !this.state.asc });
this.props.sortHandle('date', this.state.asc)
}}>
<span className="margin-r-5">Date</span>
{
this.setState({asc:!this.state.asc});
this.props.sortHandle('name',this.state.asc)
}}>
名称
{
this.setState({asc:!this.state.asc});
this.props.sortHandle('date',this.state.asc)
}}>
日期
这似乎很好,但只有在我点击分拣机2次之后。我想这和国家有关。有什么解决方案吗?也许你需要这样的解决方案
列表是您的数组
键
是要对其进行排序的键
如果要对asc
进行排序,则isAsc
为true
;如果要使用desc
进行排序,则false
compareStr = key => (a, b) => {
if (a[key] < b[key]) {
return -1
}
if (a[key] > b[key]) {
return 1
}
return 0
}
sortArray = (list, key, isAsc) => {
if (!list || !list.length) return []
const duplicate = [...list]
if (typeof duplicate[0][key] === 'number' || Number(duplicate[0][key])) {
duplicate.sort((a, b) =>
isAsc
? Number(a[key]) - Number(b[key])
: Number(b[key]) - Number(a[key])
)
return duplicate
}
duplicate.sort(compareStr(key))
if (isAsc) return duplicate
return duplicate.reverse()
}
compareStr=key=>(a,b)=>{
如果(a[键]b[键]){
返回1
}
返回0
}
sortArray=(列表、键、isAsc)=>{
如果(!list | |!list.length)返回[]
常量重复=[…列表]
如果(重复[0][key]的类型=='number'| | number(重复[0][key])){
重复。排序((a,b)=>
isAsc
?编号(a[键])-编号(b[键])
:编号(b[键])-编号(a[键])
)
返回副本
}
重复。排序(比较(键))
如果(isAsc)返回副本
返回replicate.reverse()
}
如果数组中的数字是数字,而不是字符串,那么这将很好地工作。
因此,您可以选择或更改数字类型,或者您可以添加自己的数字大小写检查,而不是此if(typeof duplicate[0][key]='number'){
这里有一个简单的小技巧。你不需要在事件处理程序中进行排序-你只需要在渲染中进行排序,只需要维护有关排序属性和顺序的信息。此外,你只需要将排序器的返回值乘以-1
如果要将顺序更改为降序
首先,我将提取分拣机本身:
const sorters = {
level: (a, b) => parseInt(a.level) - parseInt(b.level),
generation: (a, b) => parseInt(a.generation - b.generation),
name: (a, b) => a.name.localeCompare(b.name),
area: (a, b) => a.area.localeCompare(b.area),
};
很简单。然后,我会把这些和排序顺序一起放入您的状态:
const SortOrder = {
ASC: 1,
DESC: -1,
};
// ...
state = {
sortOrder: SortOrder.ASC,
sortProperty: "level",
array: [],
// ...
};
sortArray = (property, order) => {
this.setState({
sortProperty: property,
sortOrder: order === "asc" ? SortOrder.ASC : SortOrder.DESC,
});
};
然后,在render()
中,您只需获取阵列并根据分类器对其进行排序:
render() {
const { array, sortProperty, sortOrder } = this.state;
const arraySorter = sorters[sortProperty];
const displayArray = [...array].sort(
(a, b) => arraySorter(a, b) * sortOrder
);
return (
<>
{displayArray.map((item) => (
<p key={item}>{item}</p>
))}
</>
);
}
这里的API与您的API相同,即this.sortArray('level','desc')
,但老实说,您可以直接将订单
传递到排序器
,并像调用()=>this.sortArray('level',sortOrder.desc')一样调用它
。或者完全从函数中删除订单,因为您现在可以将其与属性分开更改
总而言之:
const SortOrder = {
ASC: 1,
DESC: -1,
};
const sorters = {
level: (a, b) => parseInt(a.level) - parseInt(b.level),
generation: (a, b) => parseInt(a.generation - b.generation),
name: (a, b) => a.name.localeCompare(b.name),
area: (a, b) => a.area.localeCompare(b.area),
};
class MyComponent extends React.Component {
state = {
sortOrder: SortOrder.ASC,
sortProperty: "level",
array: [],
// ...
};
sortArray = (property, order) => {
this.setState({
sortProperty: property,
sortOrder: order === "asc" ? SortOrder.ASC : SortOrder.DESC,
});
};
render() {
const { array, sortProperty, sortOrder } = this.state;
const arraySorter = sorters[sortProperty];
const displayArray = [...array].sort(
(a, b) => arraySorter(a, b) * sortOrder
);
return (
<>
{displayArray.map((item) => (
<p key={item}>{item}</p>
))}
</>
);
}
}
const SortOrder={
ASC:1,
描述:-1,
};
常量分拣机={
级别:(a,b)=>parseInt(a.level)-parseInt(b.level),
生成:(a,b)=>parseInt(a.generation-b.generation),
name:(a,b)=>a.name.localeCompare(b.name),
面积:(a,b)=>a.area.localeCompare(b.area),
};
类MyComponent扩展了React.Component{
状态={
sortOrder:sortOrder.ASC,
sortProperty:“级别”,
阵列:[],
// ...
};
Sortaray=(属性、顺序)=>{
这是我的国家({
sortProperty:属性,
sortOrder:order==“asc”?sortOrder.asc:sortOrder.DESC,
});
};
render(){
const{array,sortProperty,sortOrder}=this.state;
const arraySorter=分拣机[分拣属性];
常量displayArray=[…数组].sort(
(a,b)=>阵列排序器(a,b)*排序器
);
返回(
{displayArray.map((项)=>(
{item}
))}
);
}
}
如果你不反对使用软件包,那么它适合排序需要使用简单排序:然后将状态设置为排序数组:this.setState([…array].sort(…)
简单排序对数字不起作用无耻的自我插入:我为排序函数编写了一个助手,可能很方便:这个函数的功能()=>这个.sortArray('level','desc')是我需要从子组件的状态中获取函数参数。这意味着当我单击子组件中的某个分类器时,它触发一个通过其状态(属性,顺序)的onClick事件在父组件中使用sortArray。如果我没有很好地解释它,那么很抱歉。我仍在学习react,而且我的英语不太好。这帮了大忙。我修改了代码,只返回sortArray.reverse(),如果order==='desc',它可以工作