切片的索引排序

huangapple go评论65阅读模式
英文:

Sort indices of slice

问题

我想要对元素的索引进行排序,而不是对切片进行排序。对于[]string{"dog","cat","apple","bat"},我想要得到[]int{2,3,1,0}

package main

import (
	"fmt"
	"sort"
	"strings"
)

func main() {
	arr := []string{"dog","cat","apple","bat"}
	n := len(arr)
	indices := make([]int, n)
	for i:=0;i<n;i++{
		indices[i]=i
	}
	sort.Slice(indices, func(i,j int) bool {return strings.Compare(arr[i],arr[j])<0})
	fmt.Println(arr, indices) // [dog cat apple bat] [2 1 0 3]
	
	sort.Slice(arr, func(i,j int) bool {return strings.Compare(arr[i],arr[j])<0})
	fmt.Println(arr) //[apple bat cat dog] 
}
英文:

I want to sort the index of elements rather than sorting the slice. For []string{&quot;dog&quot;,&quot;cat&quot;,&quot;apple&quot;,&quot;bat&quot;} I want to get []int{2,3,1,0}

package main

import (
	&quot;fmt&quot;
	&quot;sort&quot;
	&quot;strings&quot;
)

func main() {
	arr := []string{&quot;dog&quot;,&quot;cat&quot;,&quot;apple&quot;,&quot;bat&quot;}
	n := len(arr)
	indices := make([]int, n)
	for i:=0;i&lt;n;i++{
		indices[i]=i
	}
	sort.Slice(indices, func(i,j int) bool {return strings.Compare(arr[i],arr[j])&lt;0})
	fmt.Println(arr, indices) // [dog cat apple bat] [2 1 0 3]
	
	sort.Slice(arr, func(i,j int) bool {return strings.Compare(arr[i],arr[j])&lt;0})
	fmt.Println(arr) //[apple bat cat dog] 
}

答案1

得分: 3

你的less()函数所接收的索引是可排序切片(indices)的索引,而不是另一个切片(arr)的索引。

因此,请使用ij来索引indices。当然,结果是要用于arr切片的索引(这是你对indices切片的定义),所以你可以使用表达式arr[indices[i]]arr[indices[j]]来获取可比较的元素。

不要使用strings.Compare(),而是使用小于<运算符直接比较字符串。详细信息请参见https://stackoverflow.com/questions/52830314/go-compare-strings/52831144#52831144。

sort.Slice(indices, func(i, j int) bool {
    return arr[indices[i]] < arr[indices[j]]
})

通过这个改变,你将得到预期的输出结果(在Go Playground上尝试一下):

[dog cat apple bat] [2 3 1 0]
[apple bat cat dog]
英文:

The indices your less() function gets are indices of the sortable slice (indices), not another (arr) slice.

So use i and j to index indices. The result of course is an index to be used for the arr slice (that's your definition of the indices slice), so you get the comparable elements using the expressions arr[indices[i] and arr[indices[j]].

And don't use strings.Compare(), simply compare strings using the less &lt; operator. For details, see https://stackoverflow.com/questions/52830314/go-compare-strings/52831144#52831144.

sort.Slice(indices, func(i, j int) bool {
	return arr[indices[i]] &lt; arr[indices[j]]
})

With this change you get your expected output (try it on the Go Playground):

[dog cat apple bat] [2 3 1 0]
[apple bat cat dog]

huangapple
  • 本文由 发表于 2022年4月18日 04:56:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/71905411.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定