1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-03-01 00:35:28 +08:00

Compare commits

...

5 Commits

Author SHA1 Message Date
dudaodong
be62aaac9b refactor: update signature of WriteMapsToCsv function
g
2024-01-24 11:54:42 +08:00
dudaodong
e0c9ccbce3 doc: add DeleteRange 2024-01-23 17:27:28 +08:00
dudaodong
d2d1e5a055 feat: refact DeleteAt and add DeleteRange function 2024-01-22 15:34:35 +08:00
dudaodong
bbc58c7e46 fix: fix the map key order issue of WriteMapsToCsv 2024-01-22 11:10:02 +08:00
dudaodong
ac2ecceaec refactor: refact reduce function 2024-01-03 10:46:28 +08:00
15 changed files with 339 additions and 165 deletions

View File

@@ -706,6 +706,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
[[play](https://go.dev/play/p/OExTkhGEd3_u)]
- **<big>WriteCsvFile</big>** : write content to target csv file.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteCsvFile)]
- **<big>WriteMapsToCsv</big>** : write slice of map to csv file.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteMapsToCsv)]
[[play](https://go.dev/play/p/dAXm58Q5U1o)]
- **<big>WriteBytesToFile</big>** : write bytes to target file.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteBytesToFile)]
@@ -1178,9 +1180,10 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>DifferenceWith</big>** : accepts comparator which is invoked to compare elements of slice to values.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#DifferenceWith)]
[[play](https://go.dev/play/p/v2U2deugKuV)]
- **<big>DeleteAt</big>** : delete the element of slice from specific start index to end index - 1.
- **<big>DeleteAt</big>** : delete the element of slice at index.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#DeleteAt)]
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
- **<big>DeleteRange</big>** : delete the element of slice from start index to end indexexclude).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#DeleteRange)]
- **<big>Drop</big>** : drop n elements from the start of a slice.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Drop)]
[[play](https://go.dev/play/p/jnPO2yQsT8H)]

View File

@@ -705,8 +705,10 @@ import "github.com/duke-git/lancet/v2/fileutil"
- **<big>ReadCsvFile</big>** : 读取 csv 文件内容到切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#ReadCsvFile)]
[[play](https://go.dev/play/p/OExTkhGEd3_u)]
- **<big>WriteCsvFile</big>** : 向 csv 文件写入内容
- **<big>WriteCsvFile</big>** : 向csv文件写入切片数据
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteCsvFile)]
- **<big>WriteMapsToCsv</big>** : 将map切片写入csv文件中。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteMapsToCsv)]
[[play](https://go.dev/play/p/dAXm58Q5U1o)]
- **<big>WriteBytesToFile</big>** : 将 bytes 写入文件。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteBytesToFile)]
@@ -1177,9 +1179,10 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>DifferenceWith</big>** : 接受比较器函数,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#DifferenceWith)]
[[play](https://go.dev/play/p/v2U2deugKuV)]
- **<big>DeleteAt</big>** : 删除切片中指定开始索引到结束索引的元素。
- **<big>DeleteAt</big>** : 删除切片中指定索引到的元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#DeleteAt)]
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
- **<big>DeleteRange</big>** : 删除切片中指定开始索引到结束索引的元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#DeleteRange)]
- **<big>Drop</big>** : 从切片头部删除 n 个元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Drop)]
[[play](https://go.dev/play/p/jnPO2yQsT8H)]

View File

@@ -45,6 +45,7 @@ import (
- [Sha](#Sha)
- [ReadCsvFile](#ReadCsvFile)
- [WriteCsvFile](#WriteCsvFile)
- [WriteMapsToCsv](#WriteMapsToCsv)
- [WriteStringToFile](#WriteStringToFile)
- [WriteBytesToFile](#WriteBytesToFile)
- [ReadFile](#ReadFile)
@@ -750,7 +751,12 @@ func main() {
<b>函数签名:</b>
```go
func WriteMapsToCsv(filepath string, records []map[string]string, append_to_existing_file bool, delimiter ...rune) error
// filepath: CSV文件路径。
// records: 写入文件的map切片。map值必须为基本类型。会以map键的字母顺序写入。
// appendToExistingFile: 是否为追加写模式。
// delimiter: CSV文件分割符。
// headers: CSV文件表头顺序需要与map key保持一致),不指定时按字母排序。
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error
```
<b>示例:</b>
@@ -770,23 +776,24 @@ func main() {
f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777)
defer f.Close()
records := []map[string]string{
{"Name": "Lili", "Age": "22", "gender": "female"},
{"Name": "Jim", "Age": "21", "gender": "male"},
records := []map[string]any{
{"Name": "Lili", "Age": "22", "Gender": "female"},
{"Name": "Jim", "Age": "21", "Gender": "male"},
}
err := WriteMapsToCsv(csvFilePath, records, false, ';')
headers := []string{"Name", "Age", "Gender"}
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
if err != nil {
log.Fatal(err)
}
content, err := ReadCsvFile(csvFilePath, ';')
content, err := fileutil.ReadCsvFile(csvFilePath, ';')
fmt.Println(content)
// Output:
// [[Name Age gender] [Lili 22 female] [Jim 21 male]]
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
}
```

View File

@@ -35,6 +35,7 @@ import (
- [DifferenceBy](#DifferenceBy)
- [DifferenceWith](#DifferenceWith)
- [DeleteAt](#DeleteAt)
- [DeleteRange](#DeleteRange)
- [Drop](#Drop)
- [DropRight](#DropRight)
- [DropWhile](#DropWhile)
@@ -516,12 +517,12 @@ func main() {
### <span id="DeleteAt">DeleteAt</span>
<p>删除切片中指定开始索引到结束索引的元素</p>
<p>删除切片中指定索引的元素(不修改原切片)。</p>
<b>函数签名:</b>
```go
func DeleteAt[T any](slice []T, start int, end ...int)
func DeleteAt[T any](slice []T, index int) []T
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/pJ-d6MUWcvK)</span></b>
@@ -533,18 +534,66 @@ import (
)
func main() {
result1 := slice.DeleteAt([]string{"a", "b", "c"}, -1)
result2 := slice.DeleteAt([]string{"a", "b", "c"}, 0)
result3 := slice.DeleteAt([]string{"a", "b", "c"}, 0, 2)
chars := []string{"a", "b", "c", "d", "e"}
result1 := slice.DeleteAt(chars, 0)
result2 := slice.DeleteAt(chars, 4)
result3 := slice.DeleteAt(chars, 5)
result4 := slice.DeleteAt(chars, 6)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// [a b c]
// [b c]
// [c]
// [b c d e]
// [a b c d]
// [a b c d]
// [a b c d]
}
```
### <span id="DeleteRange">DeleteRange</span>
<p>删除切片中指定索引范围的元素(不修改原切片)。</p>
<b>函数签名:</b>
```go
func DeleteRange[T any](slice []T, start, end int) []T
```
<b>示例:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
chars := []string{"a", "b", "c", "d", "e"}
result1 := DeleteRange(chars, 0, 0)
result2 := DeleteRange(chars, 0, 1)
result3 := DeleteRange(chars, 0, 3)
result4 := DeleteRange(chars, 0, 4)
result5 := DeleteRange(chars, 0, 5)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// [a b c d e]
// [b c d e]
// [d e]
// [e]
// []
}
```
@@ -2475,18 +2524,18 @@ import (
func main() {
nums := []int{1, 2, 3, 4, 5}
result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// [[1 2 3 4 5]]
// [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]]
// Output:
// [[1 2 3 4 5]]
// [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]]
}
```
@@ -2510,13 +2559,13 @@ import (
)
func main() {
nums := []int{1, 2, 3, 4, 5}
nums := []int{1, 2, 3, 4, 5}
val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk")
}
// Output:
// okk
val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk")
}
// Output:
// okk
}
```

View File

@@ -45,6 +45,7 @@ import (
- [Sha](#Sha)
- [ReadCsvFile](#ReadCsvFile)
- [WriteCsvFile](#WriteCsvFile)
- [WriteCsvFile](#WriteCsvFile)
- [WriteMapsToCsv](#WriteMapsToCsv)
- [WriteStringToFile](#WriteStringToFile)
- [WriteBytesToFile](#WriteBytesToFile)
@@ -751,7 +752,12 @@ func main() {
<b>Signature:</b>
```go
func WriteMapsToCsv(filepath string, records []map[string]string, append_to_existing_file bool, delimiter ...rune) error
// filepath: path of the CSV file.
// records: slice of maps to be written. the value of map should be basic type. The maps will be sorted by key in alphabeta order, then be written into csv file.
// appendToExistingFile: If true, data will be appended to the file if it exists.
// delimiter: Delimiter to use in the CSV file.
// headers: order of the csv column headers, needs to be consistent with the key of the map.
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error
```
<b>Example:</b>
@@ -771,23 +777,24 @@ func main() {
f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777)
defer f.Close()
records := []map[string]string{
{"Name": "Lili", "Age": "22", "gender": "female"},
{"Name": "Jim", "Age": "21", "gender": "male"},
records := []map[string]any{
{"Name": "Lili", "Age": "22", "Gender": "female"},
{"Name": "Jim", "Age": "21", "Gender": "male"},
}
err := WriteMapsToCsv(csvFilePath, records, false, ';')
headers := []string{"Name", "Age", "Gender"}
err := fileutil.WriteMapsToCsv(csvFilePath, records, false, ';', headers)
if err != nil {
log.Fatal(err)
}
content, err := ReadCsvFile(csvFilePath, ';')
content, err := fileutil.ReadCsvFile(csvFilePath, ';')
fmt.Println(content)
// Output:
// [[Name Age gender] [Lili 22 female] [Jim 21 male]]
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
}
```

View File

@@ -35,6 +35,7 @@ import (
- [DifferenceBy](#DifferenceBy)
- [DifferenceWith](#DifferenceWith)
- [DeleteAt](#DeleteAt)
- [DeleteRange](#DeleteRange)
- [Drop](#Drop)
- [DropRight](#DropRight)
- [DropWhile](#DropWhile)
@@ -515,12 +516,12 @@ func main() {
### <span id="DeleteAt">DeleteAt</span>
<p>Delete the element of slice from start index to end index - 1.</p>
<p>Delete delete the element of slice at index.</p>
<b>Signature:</b>
```go
func DeleteAt[T any](slice []T, start int, end ...int)
func DeleteAt[T any](slice []T, index int)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/pJ-d6MUWcvK)</span></b>
@@ -532,18 +533,66 @@ import (
)
func main() {
result1 := slice.DeleteAt([]string{"a", "b", "c"}, -1)
result2 := slice.DeleteAt([]string{"a", "b", "c"}, 0)
result3 := slice.DeleteAt([]string{"a", "b", "c"}, 0, 2)
chars := []string{"a", "b", "c", "d", "e"}
result1 := slice.DeleteAt(chars, 0)
result2 := slice.DeleteAt(chars, 4)
result3 := slice.DeleteAt(chars, 5)
result4 := slice.DeleteAt(chars, 6)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// [a b c]
// [b c]
// [c]
// [b c d e]
// [a b c d]
// [a b c d]
// [a b c d]
}
```
### <span id="DeleteRange">DeleteRange</span>
<p>Delete the element of slice from start index to end indexexclude)</p>
<b>Signature:</b>
```go
func DeleteRange[T any](slice []T, start, end int) []T
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
chars := []string{"a", "b", "c", "d", "e"}
result1 := DeleteRange(chars, 0, 0)
result2 := DeleteRange(chars, 0, 1)
result3 := DeleteRange(chars, 0, 3)
result4 := DeleteRange(chars, 0, 4)
result5 := DeleteRange(chars, 0, 5)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// [a b c d e]
// [b c d e]
// [d e]
// [e]
// []
}
```
@@ -2473,18 +2522,18 @@ import (
func main() {
nums := []int{1, 2, 3, 4, 5}
result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// [[1 2 3 4 5]]
// [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]]
// Output:
// [[1 2 3 4 5]]
// [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]]
}
```
@@ -2507,13 +2556,13 @@ import (
)
func main() {
nums := []int{1, 2, 3, 4, 5}
nums := []int{1, 2, 3, 4, 5}
val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk")
}
// Output:
// okk
val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk")
}
// Output:
// okk
}
```

View File

@@ -20,6 +20,7 @@ import (
"os"
"path/filepath"
"runtime"
"sort"
"strings"
"github.com/duke-git/lancet/v2/validator"
@@ -754,33 +755,55 @@ func escapeCSVField(field string, delimiter rune) string {
// WriteMapsToCsv write slice of map to csv file.
// Play: todo
func WriteMapsToCsv(filepath string, records []map[string]string, append_to_existing_file bool, delimiter ...rune) error {
var datas_to_write [][]string
// 标题(列名)
var headers []string
if len(records) > 0 {
for key := range records[0] {
headers = append(headers, key)
// filepath: Path to the CSV file.
// records: Slice of maps to be written. the value of map should be basic type.
// the maps will be sorted by key in alphabeta order, then be written into csv file.
// appendToExistingFile: If true, data will be appended to the file if it exists.
// delimiter: Delimiter to use in the CSV file.
// headers: order of the csv column headers, needs to be consistent with the key of the map.
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune,
headers ...[]string) error {
for _, record := range records {
for _, value := range record {
if !isCsvSupportedType(value) {
return errors.New("unsupported value type detected; only basic types are supported: \nbool, rune, string, int, int64, float32, float64, uint, byte, complex128, complex64, uintptr")
}
}
}
// 追加模式不重复写字段名
if !append_to_existing_file {
datas_to_write = append(datas_to_write, headers)
var columnHeaders []string
if len(headers) > 0 {
columnHeaders = headers[0]
} else {
for key := range records[0] {
columnHeaders = append(columnHeaders, key)
}
// sort keys in alphabeta order
sort.Strings(columnHeaders)
}
// 写入数据行
var datasToWrite [][]string
if !appendToExistingFile {
datasToWrite = append(datasToWrite, columnHeaders)
}
for _, record := range records {
var row []string
for _, header := range headers {
row = append(row, record[header])
for _, h := range columnHeaders {
row = append(row, fmt.Sprintf("%v", record[h]))
}
datas_to_write = append(datas_to_write, row)
datasToWrite = append(datasToWrite, row)
}
return WriteCsvFile(filepath, datasToWrite, appendToExistingFile, delimiter)
}
// check if the value of map which to be written into csv is basic type.
func isCsvSupportedType(v interface{}) bool {
switch v.(type) {
case bool, rune, string, int, int64, float32, float64, uint, byte, complex128, complex64, uintptr:
return true
default:
return false
}
// 提取自定义分隔符
var sep rune
if len(delimiter) > 0 {
sep = delimiter[0]
} else {
sep = ','
}
return WriteCsvFile(filepath, datas_to_write, append_to_existing_file, sep)
}

View File

@@ -3,6 +3,7 @@ package fileutil
import (
"fmt"
"io"
"log"
"os"
)
@@ -331,26 +332,27 @@ func ExampleWriteCsvFile() {
// [[Lili 22 female] [Jim 21 male]]
}
// func ExampleWriteMapsToCsv() {
// csvFilePath := "./testdata/test3.csv"
// records := []map[string]string{
// {"Name": "Lili", "Age": "22", "gender": "female"},
// {"Name": "Jim", "Age": "21", "gender": "male"},
// }
func ExampleWriteMapsToCsv() {
csvFilePath := "./testdata/test3.csv"
records := []map[string]any{
{"Name": "Lili", "Age": "22", "Gender": "female"},
{"Name": "Jim", "Age": "21", "Gender": "male"},
}
// err := WriteMapsToCsv(csvFilePath, records, false, ';')
headers := []string{"Name", "Age", "Gender"}
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
// if err != nil {
// log.Fatal(err)
// }
if err != nil {
log.Fatal(err)
}
// content, err := ReadCsvFile(csvFilePath, ';')
content, err := ReadCsvFile(csvFilePath, ';')
// fmt.Println(content) //顺序不固定
fmt.Println(content)
// // Output:
// // [[Name Age gender] [Lili 22 female] [Jim 21 male]]
// }
// Output:
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
}
func ExampleWriteStringToFile() {
filepath := "./test.txt"

View File

@@ -392,12 +392,13 @@ func TestWriteMapsToCsv(t *testing.T) {
assert := internal.NewAssert(t, "TestWriteMapsToCSV")
csvFilePath := "./testdata/test4.csv"
records := []map[string]string{
{"Name": "Lili", "Age": "22", "gender": "female"},
{"Name": "Jim", "Age": "21", "gender": "male"},
records := []map[string]any{
{"Name": "Lili", "Age": "22", "Gender": "female"},
{"Name": "Jim", "Age": "21", "Gender": "male"},
}
err := WriteMapsToCsv(csvFilePath, records, false, ';')
headers := []string{"Name", "Age", "Gender"}
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
assert.IsNil(err)
@@ -407,7 +408,9 @@ func TestWriteMapsToCsv(t *testing.T) {
assert.Equal(3, len(content))
assert.Equal(3, len(content[0]))
// assert.Equal("Lili", content[1][0])
assert.Equal("Lili", content[1][0])
assert.Equal("22", content[1][1])
assert.Equal("female", content[1][2])
}
func TestWriteStringToFile(t *testing.T) {

View File

@@ -1,3 +1,3 @@
Age;gender;Name
22;female;Lili
21;male;Jim
Name;Age;Gender
Lili;22;female
Jim;21;male
1 Name gender Age Gender
2 Lili female 22 female
3 Jim male 21 male

View File

@@ -1,3 +1,3 @@
Name;Age;gender
Name;Age;Gender
Lili;22;female
Jim;21;male
1 Name Age gender Gender
2 Lili 22 female female
3 Jim 21 male male

View File

View File

@@ -498,20 +498,13 @@ func FlatMap[T any, U any](slice []T, iteratee func(index int, item T) []U) []U
// Reduce creates an slice of values by running each element of slice thru iteratee function.
// Play: https://go.dev/play/p/_RfXJJWIsIm
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T {
if len(slice) == 0 {
return initial
accumulator := initial
for i, v := range slice {
accumulator = iteratee(i, v, accumulator)
}
result := iteratee(0, initial, slice[0])
tmp := make([]T, 2)
for i := 1; i < len(slice); i++ {
tmp[0] = result
tmp[1] = slice[i]
result = iteratee(i, tmp[0], tmp[1])
}
return result
return accumulator
}
// ReduceBy produces a value from slice by accumulating the result of each element as passed through the reducer function.
@@ -625,35 +618,34 @@ func IntSlice(slice any) []int {
return result
}
// DeleteAt delete the element of slice from start index to end index - 1.
// DeleteAt delete the element of slice at index.
// Play: https://go.dev/play/p/pJ-d6MUWcvK
func DeleteAt[T any](slice []T, start int, end ...int) []T {
size := len(slice)
if start < 0 || start >= size {
return slice
func DeleteAt[T any](slice []T, index int) []T {
if index >= len(slice) {
index = len(slice) - 1
}
if len(end) > 0 {
end := end[0]
if end <= start {
return slice
}
if end > size {
end = size
}
result := make([]T, len(slice)-1)
copy(result, slice[:index])
copy(result[index:], slice[index+1:])
slice = append(slice[:start], slice[end:]...)
return slice
return result
}
// DeleteRange delete the element of slice from start index to end indexexclude).
// Play: todo
func DeleteRange[T any](slice []T, start, end int) []T {
result := make([]T, 0, len(slice)-(end-start))
for i := 0; i < start; i++ {
result = append(result, slice[i])
}
if start == size-1 {
slice = slice[:start]
} else {
slice = append(slice[:start], slice[start+1:]...)
for i := end; i < len(slice); i++ {
result = append(result, slice[i])
}
return slice
return result
}
// Drop drop n elements from the start of a slice.

View File

@@ -594,18 +594,46 @@ func ExampleIntSlice() {
}
func ExampleDeleteAt() {
result1 := DeleteAt([]string{"a", "b", "c"}, -1)
result2 := DeleteAt([]string{"a", "b", "c"}, 0)
result3 := DeleteAt([]string{"a", "b", "c"}, 0, 2)
chars := []string{"a", "b", "c", "d", "e"}
result1 := DeleteAt(chars, 0)
result2 := DeleteAt(chars, 4)
result3 := DeleteAt(chars, 5)
result4 := DeleteAt(chars, 6)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// [a b c]
// [b c]
// [c]
// [b c d e]
// [a b c d]
// [a b c d]
// [a b c d]
}
func ExampleDeleteRange() {
chars := []string{"a", "b", "c", "d", "e"}
result1 := DeleteRange(chars, 0, 0)
result2 := DeleteRange(chars, 0, 1)
result3 := DeleteRange(chars, 0, 3)
result4 := DeleteRange(chars, 0, 4)
result5 := DeleteRange(chars, 0, 5)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// [a b c d e]
// [b c d e]
// [d e]
// [e]
// []
}
func ExampleDrop() {

View File

@@ -572,19 +572,27 @@ func TestDeleteAt(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestDeleteAt")
arr := []int{1, 2, 3, 4, 5}
assert.Equal([]string{"a", "b", "c"}, DeleteAt([]string{"a", "b", "c"}, -1))
assert.Equal([]string{"a", "b", "c"}, DeleteAt([]string{"a", "b", "c"}, 3))
assert.Equal([]string{"b", "c"}, DeleteAt([]string{"a", "b", "c"}, 0))
assert.Equal([]string{"a", "c"}, DeleteAt([]string{"a", "b", "c"}, 1))
assert.Equal([]string{"a", "b"}, DeleteAt([]string{"a", "b", "c"}, 2))
assert.Equal([]int{2, 3, 4, 5}, DeleteAt(arr, 0))
assert.Equal([]int{1, 2, 3, 4}, DeleteAt(arr, 4))
assert.Equal([]string{"b", "c"}, DeleteAt([]string{"a", "b", "c"}, 0, 1))
assert.Equal([]string{"c"}, DeleteAt([]string{"a", "b", "c"}, 0, 2))
assert.Equal([]string{}, DeleteAt([]string{"a", "b", "c"}, 0, 3))
assert.Equal([]string{}, DeleteAt([]string{"a", "b", "c"}, 0, 4))
assert.Equal([]string{"a"}, DeleteAt([]string{"a", "b", "c"}, 1, 3))
assert.Equal([]string{"a"}, DeleteAt([]string{"a", "b", "c"}, 1, 4))
assert.Equal([]int{1, 2, 3, 4}, DeleteAt(arr, 5))
assert.Equal([]int{1, 2, 3, 4}, DeleteAt(arr, 6))
assert.Equal([]int{1, 2, 3, 4, 5}, arr)
}
func TestDeleteRange(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestDeleteRange")
arr := []int{1, 2, 3, 4, 5}
assert.Equal([]int{1, 2, 3, 4, 5}, DeleteRange(arr, 0, 0))
assert.Equal([]int{2, 3, 4, 5}, DeleteRange(arr, 0, 1))
assert.Equal([]int{4, 5}, DeleteRange(arr, 0, 3))
}
func TestDrop(t *testing.T) {