mirror of
https://github.com/samber/lo.git
synced 2026-04-22 15:37:14 +08:00
fa095e4b4f
* fix(doc): fix go playground demo URL * fix(doc): add more go playground demo URL
177 lines
5.3 KiB
Markdown
177 lines
5.3 KiB
Markdown
---
|
|
name: ElementsMatchBy
|
|
slug: elementsmatchby
|
|
sourceRef: it/intersect.go#L183
|
|
category: it
|
|
subCategory: intersect
|
|
signatures:
|
|
- "func ElementsMatchBy[T any, K comparable](list1, list2 iter.Seq[T], transform func(item T) K) bool"
|
|
playUrl: "https://go.dev/play/p/I3vFrmQo43E"
|
|
variantHelpers:
|
|
- it#intersect#elementsmatchby
|
|
similarHelpers:
|
|
- core#slice#elementsmatchby
|
|
position: 730
|
|
---
|
|
|
|
Returns true if lists contain the same set of elements' keys (including empty set).
|
|
|
|
If there are duplicate keys, the number of occurrences in each list should match.
|
|
The order of elements is not checked.
|
|
Will iterate through each sequence before returning and allocate a map large enough to hold all distinct transformed elements.
|
|
Long heterogeneous input sequences can cause excessive memory usage.
|
|
|
|
Examples:
|
|
|
|
```go
|
|
// Match people by age (ignoring names)
|
|
type Person struct {
|
|
Name string
|
|
Age int
|
|
}
|
|
people1 := it.Slice([]Person{
|
|
{Name: "Alice", Age: 30},
|
|
{Name: "Bob", Age: 25},
|
|
{Name: "Charlie", Age: 35},
|
|
})
|
|
people2 := it.Slice([]Person{
|
|
{Name: "David", Age: 35},
|
|
{Name: "Eve", Age: 25},
|
|
{Name: "Frank", Age: 30},
|
|
})
|
|
match := it.ElementsMatchBy(people1, people2, func(p Person) int { return p.Age })
|
|
// match: true (both have ages 25, 30, 35)
|
|
|
|
// Match by string length
|
|
words1 := it.Slice([]string{"hello", "world", "go", "lang"})
|
|
words2 := it.Slice([]string{"short", "longer", "golang", "python"})
|
|
match = it.ElementsMatchBy(words1, words2, func(s string) int { return len(s) })
|
|
// match: false (lengths: 5,5,2,4 vs 6,6,6,6)
|
|
|
|
// Match by first character
|
|
items1 := it.Slice([]string{"apple", "apricot", "banana", "blueberry"})
|
|
items2 := it.Slice([]string{"ant", "anchor", "boat", "berry"})
|
|
match = it.ElementsMatchBy(items1, items2, func(s string) byte { return s[0] })
|
|
// match: true (both start with a, a, b, b)
|
|
|
|
// Match emails by domain
|
|
type Email struct {
|
|
Address string
|
|
}
|
|
emails1 := it.Slice([]Email{
|
|
{Address: "user1@example.com"},
|
|
{Address: "user2@gmail.com"},
|
|
{Address: "user3@example.com"},
|
|
})
|
|
emails2 := it.Slice([]Email{
|
|
{Address: "different@gmail.com"},
|
|
{Address: "another@example.com"},
|
|
{Address: "third@example.com"},
|
|
})
|
|
match = it.ElementsMatchBy(emails1, emails2, func(e Email) string {
|
|
parts := strings.Split(e.Address, "@")
|
|
if len(parts) > 1 {
|
|
return parts[1]
|
|
}
|
|
return ""
|
|
})
|
|
// match: true (both have domains: example.com, gmail.com, example.com)
|
|
|
|
// Match by modulo operation
|
|
numbers1 := it.Slice([]int{1, 2, 3, 4, 5, 6})
|
|
numbers2 := it.Slice([]int{7, 8, 9, 10, 11, 12})
|
|
match = it.ElementsMatchBy(numbers1, numbers2, func(n int) int { return n % 3 })
|
|
// match: true (remainders: 1,2,0,1,2,0 vs 1,2,0,1,2,0)
|
|
|
|
// Match by case-insensitive strings
|
|
strings1 := it.Slice([]string{"Hello", "World", "GO"})
|
|
strings2 := it.Slice([]string{"hello", "world", "go"})
|
|
match = it.ElementsMatchBy(strings1, strings2, func(s string) string { return strings.ToLower(s) })
|
|
// match: true
|
|
|
|
// Match orders by customer ID (ignoring order details)
|
|
type Order struct {
|
|
ID string
|
|
CustomerID string
|
|
ProductID string
|
|
}
|
|
orders1 := it.Slice([]Order{
|
|
{ID: "1", CustomerID: "A", ProductID: "X"},
|
|
{ID: "2", CustomerID: "B", ProductID: "Y"},
|
|
{ID: "3", CustomerID: "A", ProductID: "Z"},
|
|
})
|
|
orders2 := it.Slice([]Order{
|
|
{ID: "4", CustomerID: "B", ProductID: "W"},
|
|
{ID: "5", CustomerID: "A", ProductID: "V"},
|
|
{ID: "6", CustomerID: "A", ProductID: "U"},
|
|
})
|
|
match = it.ElementsMatchBy(orders1, orders2, func(o Order) string { return o.CustomerID })
|
|
// match: true (both have customer IDs: A, B, A)
|
|
|
|
// Match dates by year-month (ignoring day)
|
|
import "time"
|
|
dates1 := it.Slice([]time.Time{
|
|
time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
|
|
time.Date(2023, 2, 20, 0, 0, 0, 0, time.UTC),
|
|
time.Date(2023, 1, 25, 0, 0, 0, 0, time.UTC),
|
|
})
|
|
dates2 := it.Slice([]time.Time{
|
|
time.Date(2023, 1, 5, 0, 0, 0, 0, time.UTC),
|
|
time.Date(2023, 2, 10, 0, 0, 0, 0, time.UTC),
|
|
time.Date(2023, 1, 30, 0, 0, 0, 0, time.UTC),
|
|
})
|
|
match = it.ElementsMatchBy(dates1, dates2, func(t time.Time) string {
|
|
return fmt.Sprintf("%d-%02d", t.Year(), t.Month())
|
|
})
|
|
// match: true (both have: 2023-01, 2023-02, 2023-01)
|
|
|
|
// Match by category function
|
|
type Product struct {
|
|
Name string
|
|
Price float64
|
|
}
|
|
products1 := it.Slice([]Product{
|
|
{Name: "Book", Price: 19.99},
|
|
{Name: "Pen", Price: 1.99},
|
|
{Name: "Laptop", Price: 999.99},
|
|
})
|
|
products2 := it.Slice([]Product{
|
|
{Name: "Pencil", Price: 0.99},
|
|
{Name: "Phone", Price: 699.99},
|
|
{Name: "Desk", Price: 199.99},
|
|
})
|
|
match = it.ElementsMatchBy(products1, products2, func(p Product) string {
|
|
if p.Price < 10 {
|
|
return "cheap"
|
|
} else if p.Price < 100 {
|
|
return "medium"
|
|
}
|
|
return "expensive"
|
|
})
|
|
// match: true (both have: medium, cheap, expensive)
|
|
|
|
// Match by custom classification
|
|
type Student struct {
|
|
Name string
|
|
Age int
|
|
}
|
|
students1 := it.Slice([]Student{
|
|
{Name: "Alice", Age: 8},
|
|
{Name: "Bob", Age: 15},
|
|
{Name: "Charlie", Age: 20},
|
|
})
|
|
students2 := it.Slice([]Student{
|
|
{Name: "Diana", Age: 25},
|
|
{Name: "Eve", Age: 10},
|
|
{Name: "Frank", Age: 12},
|
|
})
|
|
match = it.ElementsMatchBy(students1, students2, func(s Student) string {
|
|
if s.Age < 12 {
|
|
return "child"
|
|
} else if s.Age < 18 {
|
|
return "teen"
|
|
}
|
|
return "adult"
|
|
})
|
|
// match: false (students1: child, teen, adult vs students2: adult, child, child)
|
|
``` |