Skip to content

Commit 2876510

Browse files
committed
CrossJoinX + CrossJoinByX
1 parent c4ae516 commit 2876510

6 files changed

+758
-69
lines changed

README.md

+32-14
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ Supported helpers for slices:
122122
- [IsSorted](#issorted)
123123
- [IsSortedByKey](#issortedbykey)
124124
- [Splice](#Splice)
125-
- [CrossJoin](#CrossJoin)
126125

127126
Supported helpers for maps:
128127

@@ -178,6 +177,8 @@ Supported helpers for tuples:
178177
- [ZipBy2 -> ZipBy9](#zipby2---zipby9)
179178
- [Unzip2 -> Unzip9](#unzip2---unzip9)
180179
- [UnzipBy2 -> UnzipBy9](#unzipby2---unzipby9)
180+
- [CrossJoin2 -> CrossJoin2](#crossjoin2---crossjoin9)
181+
- [CrossJoinBy2 -> CrossJoinBy2](#crossjoinby2---crossjoinby9)
181182

182183
Supported helpers for time and duration:
183184

@@ -1064,19 +1065,6 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2")
10641065

10651066
[[play](https://go.dev/play/p/wiG6XyBBu49)]
10661067

1067-
### CrossJoin
1068-
1069-
CrossJoin calculates the cartesian product of two lists. It returns a list of tuples where the first element includes the elements of the first parameter, and the second element contains the elements of the second parameter.
1070-
1071-
It returns an empty list if either, or both parameters are empty
1072-
1073-
```go
1074-
result := lo.CrossJoin([]string{"a", "b", "c"}, []int{1, 2, 3})
1075-
// [][2]interface{}{{"a", 1}, {"a", 2}, {"a", 3}, {"b", 1}, {"b", 2}, {"b", 3}, {"c", 1}, {"c", 2}, {"c", 3}
1076-
```
1077-
1078-
[[play](https://go.dev/play/p/2-DOGciKvAB)]
1079-
10801068
### Keys
10811069

10821070
Creates a slice of the map keys.
@@ -1710,6 +1698,36 @@ a, b := lo.UnzipBy2([]string{"hello", "john", "doe"}, func(str string) (string,
17101698
// []int{5, 4, 3}
17111699
```
17121700

1701+
### CrossJoin2 -> CrossJoin9
1702+
1703+
Combines every items from one list with every items from others. It is the cartesian product of lists received as arguments. It returns an empty list if a list is empty.
1704+
1705+
```go
1706+
result := lo.CrossJoin2([]string{"hello", "john", "doe"}, []int{1, 2})
1707+
// lo.Tuple2{"hello", 1}
1708+
// lo.Tuple2{"hello", 2}
1709+
// lo.Tuple2{"john", 1}
1710+
// lo.Tuple2{"john", 2}
1711+
// lo.Tuple2{"doe", 1}
1712+
// lo.Tuple2{"doe", 2}
1713+
```
1714+
1715+
### CrossJoinBy2 -> CrossJoinBy9
1716+
1717+
Combines every items from one list with every items from others. It is the cartesian product of lists received as arguments. The project function is used to create the output values. It returns an empty list if a list is empty.
1718+
1719+
```go
1720+
result := lo.CrossJoinBy2([]string{"hello", "john", "doe"}, []int{1, 2}, func(a A, b B) string {
1721+
return fmt.Sprintf("%s - %d", a, b)
1722+
})
1723+
// "hello - 1"
1724+
// "hello - 2"
1725+
// "john - 1"
1726+
// "john - 2"
1727+
// "doe - 1"
1728+
// "doe - 2"
1729+
```
1730+
17131731
### Duration
17141732

17151733
Returns the time taken to execute a function.

slice.go

-24
Original file line numberDiff line numberDiff line change
@@ -708,27 +708,3 @@ func Splice[T any, Slice ~[]T](collection Slice, i int, elements ...T) Slice {
708708

709709
return append(append(append(output, collection[:i]...), elements...), collection[i:]...)
710710
}
711-
712-
// CrossJoin calculates the cartesian product of two lists. It returns a list of
713-
// tuples where the first element includes the elements of the first parameter, and
714-
// the second element contains the elements of the second parameter.
715-
716-
// It returns an empty list if either, or both parameters are empty
717-
718-
// Play: https://go.dev/play/p/2-DOGciKvAB
719-
func CrossJoin[T, U any](listOne []T, listTwo []U) [][2]interface{} {
720-
721-
if len(listOne) == 0 || len(listTwo) == 0 {
722-
return make([][2]interface{}, 0)
723-
}
724-
725-
cartesianProduct := make([][2]interface{}, 0, len(listOne)*len(listTwo))
726-
727-
for _, a := range listOne {
728-
for _, b := range listTwo {
729-
cartesianProduct = append(cartesianProduct, [2]interface{}{a, b})
730-
}
731-
}
732-
733-
return cartesianProduct
734-
}

slice_test.go

-31
Original file line numberDiff line numberDiff line change
@@ -1046,34 +1046,3 @@ func TestSplice(t *testing.T) {
10461046
nonempty := Splice(allStrings, 1, "1", "2")
10471047
is.IsType(nonempty, allStrings, "type preserved")
10481048
}
1049-
1050-
func TestCrossJoin(t *testing.T) {
1051-
t.Parallel()
1052-
is := assert.New(t)
1053-
1054-
listOne := []string{"a", "b", "c"}
1055-
listTwo := []int{1, 2, 3}
1056-
emptyList := make([][2]any, 0)
1057-
mixedList := []any{9.6, 4, "foobar"}
1058-
1059-
results := CrossJoin(emptyList, listTwo)
1060-
is.Equal(emptyList, results)
1061-
1062-
results = CrossJoin(listOne, emptyList)
1063-
is.Equal(emptyList, results)
1064-
1065-
results = CrossJoin(emptyList, emptyList)
1066-
is.Equal(emptyList, results)
1067-
1068-
results = CrossJoin([]string{"a"}, listTwo)
1069-
is.Equal([][2]any{{"a", 1}, {"a", 2}, {"a", 3}}, results)
1070-
1071-
results = CrossJoin(listOne, []int{1})
1072-
is.Equal([][2]any{{"a", 1}, {"b", 1}, {"c", 1}}, results)
1073-
1074-
results = CrossJoin(listOne, listTwo)
1075-
is.Equal([][2]any{{"a", 1}, {"a", 2}, {"a", 3}, {"b", 1}, {"b", 2}, {"b", 3}, {"c", 1}, {"c", 2}, {"c", 3}}, results)
1076-
1077-
results = CrossJoin(listOne, mixedList)
1078-
is.Equal([][2]any{{"a", 9.6}, {"a", 4}, {"a", "foobar"}, {"b", 9.6}, {"b", 4}, {"b", "foobar"}, {"c", 9.6}, {"c", 4}, {"c", "foobar"}}, results)
1079-
}

0 commit comments

Comments
 (0)