Go:对数组进行排序,如果在`Less(i, j int)`函数中捕获到错误,则丢弃元素。

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

Go: Sort array, dropping elements if error caught in `Less(i, j int)`

问题

给定以下的struct

type Point struct {
	datetimeRecorded time.Time
}

// 如果点在比较点之前记录,则返回true。
// 如果没有可用的日期时间,则返回false和错误。
func (p1 Point) RecordedBefore(p2 Point) (isBefore bool, err error) {
	if (p1.datetimeRecorded.IsZero()) || (p2.datetimeRecorded.IsZero()) {
		err = ErrNoDatetime
	} else {
		isBefore = p1.datetimeRecorded.Before(p2.datetimeRecorded)
	}
	return
}

我想通过datetimeRecorded属性对[]Point进行排序。

我有以下代码(可以工作):

type ByDatetimeRecorded []Point

func (a ByDatetimeRecorded) Len() int {
	return len(a)
}

func (a ByDatetimeRecorded) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a ByDatetimeRecorded) Less(i, j int) bool {
	swap, _ := a[i].RecordedBefore(a[j])
	return swap
}

然而,如果datetimeRecorded属性在比较中没有被初始化,会捕获到一个error,并且点不会被交换(返回false)。

是否可能捕获此错误并将其从数组中删除?类似于:

func (a ByDatetimeRecorded) Less(i, j int) bool {
	swap, err := a[i].RecordedBefore(a[j])
    if err != nil {
        // 在这里删除元素
    }
	return swap
}

编辑1

我可能需要更具体地说明要删除的元素,这样可能更有意义:

func (a ByDatetimeRecorded) Less(i, j int) bool {
	if a[i].datetimeRecorded.IsZero() {
		// 删除a[i]
	}
	if a[j].datetimeRecorded.IsZero() {
		// 删除a[j]
	}
    swap, _ := a[i].RecordedBefore(a[j])
    return swap
}
英文:

Given the following struct

type Point struct {
	datetimeRecorded time.Time
}

// Returns true if the point was recorded before the comparison point.
// If datetime is not available return false and an error
func (p1 Point) RecordedBefore(p2 Point) (isBefore bool, err error) {
	if (p1.datetimeRecorded.IsZero()) || (p2.datetimeRecorded.IsZero()) {
		err = ErrNoDatetime
	} else {
		isBefore = p1.datetimeRecorded.Before(p2.datetimeRecorded)
	}
	return
}

I would like to sort a []Point by the datetimeRecorded attribute.

I have the following (which works):

type ByDatetimeRecorded []Point

func (a ByDatetimeRecorded) Len() int {
	return len(a)
}

func (a ByDatetimeRecorded) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a ByDatetimeRecorded) Less(i, j int) bool {
	swap, _ := a[i].RecordedBefore(a[j])
	return swap
}

However, if the datetimeRecorded attribute is not initialised in either comparison an error will be caught and the points not swapped (returns false).

Is it possible to catch this error and drop it from the array? Something like:

func (a ByDatetimeRecorded) Less(i, j int) bool {
	swap, err := a[i].RecordedBefore(a[j])
    if err != nil {
        // Remove element here
    }
	return swap
}

Edit 1

I may have to be more specific about what element to drop so this may make more sense:

func (a ByDatetimeRecorded) Less(i, j int) bool {
	if a[i].datetimeRecorded.IsZero() {
		// Drop a[i]
	}
	if a[j].datetimeRecorded.IsZero() {
		// Drop a[j]
	}
    swap, _ := a[i].RecordedBefore(a[j])
    return swap
}

答案1

得分: 2

标准的排序包不会从切片中删除元素。
在排序之前,先将切片中的零值过滤掉。

i := 0
for _, p := range points {
if !p.datetimeRecorded.IsZero() {
points[i] = p
i++
}
}
points = points[:i]
sort.Sort(ByDatetimeRecorded(points))

英文:

The standard sort package will not drop elements from the slice.
Filter the zero values out of the slice before sorting.

  i := 0
  for _, p := range points {
      if !p.datetimeRecorded.IsZero() {
         points[i] = p
         i++
      }
  }
  points = points[:i]
  sort.Sort(ByDatetimeRecorded(points))

huangapple
  • 本文由 发表于 2014年10月17日 21:42:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/26426384.html
匿名

发表评论

匿名网友

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

确定