Reducing Slice Length

Hello,

I am trying to reduce a slice’s length using a maximum count parameter. Here is the code. It is quite ok. But I am open for advices :slight_smile:

package main

import "fmt"

func main() {
	records := selectRecords(1000)
	fmt.Println(len(records))
}

func selectRecords(maximumRecordCount float64) []string {
	records := make([]string, 5987)
	recordCount := float64(len(records))
	if recordCount <= maximumRecordCount {
		return records
	}
	step := recordCount / maximumRecordCount
	var filteredRecords []string
	for i := 0.0; i < recordCount; i += step {
		filteredRecords = append(filteredRecords, records[int(i)])
	}
	return filteredRecords
}

Why don’t you just do

records := make([]string, int(maximumRecordCount))

in the first place?

It is a sample. I am selecting actual records from database regarding a date range.

I think what you’re looking for is

func selectRecords(maximumRecordCount int) []string {
	records := make([]string, 5987)
	if len(records) > maximumRecordCount {
		return records[:maximumRecordCount]
	}
	return records
}

Note that this will still use the same amount of memory as your original records slice, but iterating over the results will be limited to the maximumRecordCount. If you want to actually free the larger slice, you have to copy the data to a smaller slice:

func selectRecords(maximumRecordCount int) []string {
	records := make([]string, 5987)
	if len(records) <= maximumRecordCount {
		return records
	}
	limited := make([]string, maximumRecordCount)
	copy(limited, records)
	return limited
}

I recommend not using float64 to keep track of length. What happens if someone passes in 1.3? Should the length round down to 1 or should it round up to 2? Just pass an int to push that question off to the caller so that your function only has to worry about one thing.

1 Like

Thanks for the idea. Sorry for adding late, i will send the data from backend and print these records on a chart in frontend. Removal of records must be balanced.
For example i get [a, b, c, d, e] 5 records. I want to reduce its length to [a, c, e] 3 records.

The maximum visible point count looks like 1000 thousand and i get like 150000 thousand records :slight_smile:

What determines which records should be omitted? What’s better about returning [a, c, e] than returning [a, b, c]?

I select records (which has a value and a timestamp) using a date range. So showing records whose extra records are omited with equal steps feels more correct am i right?

It’s hard to answer without knowing the scenario. If the query is to get N days with the highest income for the month or the average number of orders completed per day, then dropping rows isn’t the right way to calculate that. You should instead aggregate the data into a smaller data set. Can you provide more information about where you’re going to use this selectRecords function?

I am using them in a server monitoring tool which i am writing to learn. Their value change is smaller and interval is 15 seconds.

Hello,

Since the slice was records of system utilizations recorded in a configured interval, i decided to reduce slice length (record count) with using a random generated index slice which has given length and start and end set. Everytime i refresh frontend it gives random chart :slight_smile: Here is the code. I am happy with the result. Thanks for your ideas.

And response time is reduced by approximately %30

https://play.golang.org/p/J69PqAB44SU

a:=make([]string,0,1000)