mirror of
https://github.com/rjNemo/underscore
synced 2026-06-06 02:26:42 +00:00
Adding a Unit test for JoinProject function
Updated the comments on the Join & OrderBy functions so they make a little more sense. Covered an extra test case with the Join test, where the left set has more data than the right and so the Right handside array of the join is empty
This commit is contained in:
parent
a72da82172
commit
581929a555
3 changed files with 39 additions and 24 deletions
25
join.go
25
join.go
|
|
@ -1,7 +1,7 @@
|
||||||
package underscore
|
package underscore
|
||||||
|
|
||||||
// Joins two slices together and returns a Tuple of [T, []P], the selectors allow you to pick the
|
// Joins two slices together and returns a Tuple of [T, []P], the selectors allow you to pick the
|
||||||
// keys from your structure you would like to join the sets together with
|
// keys you want to use from your struct's to join the sets together
|
||||||
func Join[T, P any, S comparable](
|
func Join[T, P any, S comparable](
|
||||||
left []T,
|
left []T,
|
||||||
right []P,
|
right []P,
|
||||||
|
|
@ -18,18 +18,17 @@ func Join[T, P any, S comparable](
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
// Joins two slices together and returns a []R where R is defined by the output of your projection
|
// Joins two slices together and returns a []O where O is defined by the output
|
||||||
// function
|
// of your projection function
|
||||||
// The selectors allow you to pick the keys from your structure you would like to join the sets
|
// The selectors allow you to pick the keys from your structure to use as the join keys
|
||||||
// together with.
|
// While the projection functions allows you to reformat joined datasets
|
||||||
// While the projection functions allows you to reformat joined datasets contains in the
|
// (Tuple of [T, []P]) into your own struct or type
|
||||||
// Tuple of [T, []P] into your own structure or type
|
func JoinProject[L, R, O any, S comparable](
|
||||||
func JoinProject[T, P, R any, S comparable](
|
left []L,
|
||||||
left []T,
|
right []R,
|
||||||
right []P,
|
leftSelector func(L) S,
|
||||||
leftSelector func(T) S,
|
rightSelector func(R) S,
|
||||||
rightSelector func(P) S,
|
projection func(Tuple[L, []R]) O) (results []O) {
|
||||||
projection func(Tuple[T, []P]) R) (results []R) {
|
|
||||||
|
|
||||||
for _, x := range Join(left, right, leftSelector, rightSelector) {
|
for _, x := range Join(left, right, leftSelector, rightSelector) {
|
||||||
results = append(results, projection(x))
|
results = append(results, projection(x))
|
||||||
|
|
|
||||||
33
join_test.go
33
join_test.go
|
|
@ -1,30 +1,45 @@
|
||||||
package underscore_test
|
package underscore_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
u "github.com/rjNemo/underscore"
|
u "github.com/rjNemo/underscore"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_Join_Can_Join_Two_Slices_Together(t *testing.T) {
|
var zero = u.Tuple[int, string]{Left: 0, Right: "Zero"}
|
||||||
one := u.Tuple[int, string]{Left: 1, Right: "One"}
|
var one = u.Tuple[int, string]{Left: 1, Right: "One"}
|
||||||
two := u.Tuple[int, string]{Left: 2, Right: "Two"}
|
var two = u.Tuple[int, string]{Left: 2, Right: "Two"}
|
||||||
three := u.Tuple[int, string]{Left: 3, Right: "Three"}
|
var three = u.Tuple[int, string]{Left: 3, Right: "Three"}
|
||||||
|
|
||||||
var left = []u.Tuple[int, string]{one, two, three}
|
func Test_Join_Can_Join_Two_Slices_Together(t *testing.T) {
|
||||||
|
var left = []u.Tuple[int, string]{zero, one, two, three}
|
||||||
var right = []u.Tuple[int, string]{one, three, two, three, two, three}
|
var right = []u.Tuple[int, string]{one, three, two, three, two, three}
|
||||||
|
|
||||||
selector := func(x u.Tuple[int, string]) int { return x.Left }
|
selector := func(x u.Tuple[int, string]) int { return x.Left }
|
||||||
|
|
||||||
var joined = u.Join(left, right, selector, selector)
|
var joined = u.Join(left, right, selector, selector)
|
||||||
var want = []u.Tuple[u.Tuple[int, string], []u.Tuple[int, string]]{
|
var want = []u.Tuple[u.Tuple[int, string], []u.Tuple[int, string]]{
|
||||||
|
{Left: zero, Right: nil},
|
||||||
{Left: one, Right: []u.Tuple[int, string]{one}},
|
{Left: one, Right: []u.Tuple[int, string]{one}},
|
||||||
{Left: two, Right: []u.Tuple[int, string]{two, two}},
|
{Left: two, Right: []u.Tuple[int, string]{two, two}},
|
||||||
{Left: three, Right: []u.Tuple[int, string]{three, three, three}},
|
{Left: three, Right: []u.Tuple[int, string]{three, three, three}},
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(joined, want) {
|
assert.Equal(t, want, joined)
|
||||||
t.Errorf("Expected to get %v but we got %v instead", want, joined)
|
}
|
||||||
}
|
|
||||||
|
func Test_Join_Can_Join_and_Project_Two_Slices_Together(t *testing.T) {
|
||||||
|
var left = []u.Tuple[int, string]{zero, one, two, three}
|
||||||
|
var right = []u.Tuple[int, string]{one, three, two, three, two, three}
|
||||||
|
|
||||||
|
selector := func(x u.Tuple[int, string]) int { return x.Left }
|
||||||
|
project := func(x u.Tuple[u.Tuple[int, string], []u.Tuple[int, string]]) int {
|
||||||
|
return len(x.Right) // projecting to a could of how many
|
||||||
|
}
|
||||||
|
|
||||||
|
var joined = u.JoinProject(left, right, selector, selector, project)
|
||||||
|
var want = []int{0, 1, 2, 3}
|
||||||
|
|
||||||
|
assert.Equal(t, want, joined)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
package underscore
|
package underscore
|
||||||
|
|
||||||
// Orders a slice by a field value within a struct, the predicate allow you
|
// Orders a slice by a field value within a struct, the predicate allows you
|
||||||
// to pick the fields you want to orderBy. Use > for ASC or < for DESC
|
// to pick the fields you want to orderBy. Use > for ASC or < for DESC
|
||||||
// func (left Person, right Person) bool { return person.Age > person.Age }
|
// func (left Person, right Person) bool { return left.Age > right.Age }
|
||||||
func OrderBy[T any](list []T, predicate func(T, T) bool) []T {
|
func OrderBy[T any](list []T, predicate func(T, T) bool) []T {
|
||||||
swaps := true
|
swaps := true
|
||||||
var tmp T
|
var tmp T
|
||||||
|
|
||||||
|
//todo: replace with a faster algorithm, this one is pretty simple
|
||||||
for swaps {
|
for swaps {
|
||||||
swaps = false
|
swaps = false
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue