对象数组中按对象的指定某个字段排序

                           筚路蓝缕,以启山林。抚有蛮夷,以属华夏。不鸣则已,一鸣惊人。
                                                                                                              ——《左传`宣公十二年》

 

目录

 

问题背景

解决思路

方案1代码实现

方案2代码实现


问题背景

今天遇到一个现象,因部分因素形成了信息列表infoList数组,该数组内每个元素是一个Info对象,Info有一个属性LoginTime,现在数组内对象是LoginTime乱序的,要求数组中所有对象按LoginTime由近及远的顺序排序,即结果中第一个元素应该是最新的(LoginTime最大),其它次之。

解决思路

第一种方案:既然要按LoginTime排序,那么必先取出所有对象的LoginTime排一下,那怎样让每个LoginTime关联到自己的对象呢?那就是map了,map的value用来存对应的对象,那如果有LoginTime相等也就是map的key冲突的时候呢?,那就直接append一下放一起就可以了(我这无需进一步按其它字段排序)。

第二种方案:使用sort包即可完成该需求。

方案1代码实现

// 用来给LoginTime排序
func qSort(arr []int32) []int32 {
	if len(arr) <= 1 {
		return arr
	}

	base := arr[0]
	left, right := 0, len(arr)-1
	for i := 1; i <= right; {
		if arr[i] < base {
			if i != right {
				arr[i], arr[right] = arr[right], arr[i]
			}
			right--
		} else {
			if i != left {
				arr[i], arr[left] = arr[left], arr[i]
			}
			left++
			i++
		}
	}

	qSort(arr[:left])
	qSort(arr[left+1:])
	return arr
}

// 对象数组中的对象类型:Info
// 对入参infoList中的对象进行排序,返回排好序的resList
func SortListByLoginTime(infoList []Info) (resList []Info) {
	storgeSortMap := make(map[int32][]Info)
	var ltList []int32
	for _, info := range infoList {
		if data, ok := storgeSortMap[info.LoginTime]; ok {
			storgeSortMap[info.LoginTime] = append(data, info)
		} else {
			storgeSortMap[info.LoginTime] = []Info{info}
		}

		ltList = append(ltList, info.LoginTime)
	}

	qSort(ltList)

	for _, lt := range ltList {
		if _, ok := storgeSortMap[lt]; ok {
			resList = append(resList, storgeSortMap[lt]...)
		}
		delete(storgeSortMap, lt)
	}

	return resList
}

来验证一下

func TestSortListByLoginTime(t *testing.T) {

	i1 := Info{
		Id:        1010,
		LoginTime: 123,
		NickName:  "wl123",
	}
	i2 := Info{
		Id:        1011,
		LoginTime: 125,
		NickName:  "wl125",
	}
	i3 := Info{
		Id:        1012,
		LoginTime: 121,
		NickName:  "wl121",
	}
	i4 := Info{
		Id:        1013,
		LoginTime: 131,
		NickName:  "wl131",
	}
	i5 := Info{
		Id:        1014,
		LoginTime: 117,
		NickName:  "wl117",
	}

	infoList := []Info{i1, i2, i3, i4, i5}
	log.Println("sort pre--->", infoList)
	res := SortListByLoginTime(infoList)
	log.Println("after sort--->", res)

}

测试结果(对象的第四项是LoginTime字段值):

sort pre---> [{1010  wl123  0 123 0   } {1011  wl125  0 125 0   } {1012  wl121  0 121 0   } {1013  wl131  0 131 0   } {1014  wl117  0 117 0   }]
after sort---> [{1013  wl131  0 131 0   } {1011  wl125  0 125 0   } {1010  wl123  0 123 0   } {1012  wl121  0 121 0   } {1014  wl117  0 117 0   }]

方案2代码实现

// 精简成三个字段,好观察,主要是LoginTime
type Info struct{
	Id int
	LoginTime int32
	NickName string
}

type InfoList []Info

func (list InfoList) Len() int {
	return len(list)
}

func (list InfoList) Swap(i, j int) {
	list[i], list[j] = list[j], list[i]
}

func (list InfoList) Less(i, j int) bool {
	return list[i].LoginTime > list[j].LoginTime
}

func SortListByLoginTime(infoList InfoList) {
	sort.Sort(infoList)
}

func main() {
	i1 := Info{
		Id:        1010,
		LoginTime: 123,
		NickName:  "wl123",
	}
	i2 := Info{
		Id:        1011,
		LoginTime: 125,
		NickName:  "wl125",
	}
	i3 := Info{
		Id:        1012,
		LoginTime: 121,
		NickName:  "wl121",
	}
	i4 := Info{
		Id:        1013,
		LoginTime: 131,
		NickName:  "wl131",
	}
	i5 := Info{
		Id:        1014,
		LoginTime: 117,
		NickName:  "wl117",
	}

	infoList := []Info{i1, i2, i3, i4, i5}
	log.Println("sort pre--->", infoList)
	SortListByLoginTime(infoList)
	log.Println("after sort--->", infoList)

}

验证下

sort pre---> [{1010 123 wl123} {1011 125 wl125} {1012 121 wl121} {1013 131 wl131} {1014 117 wl117}]
after sort---> [{1013 131 wl131} {1011 125 wl125} {1010 123 wl123} {1012 121 wl121} {1014 117 wl117}]

美滋滋!如果解决了你的问题,可以点个赞哦!

 

 

你可能感兴趣的:(#,go)