Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: slices: add difference function #58730

Closed
cuishuang opened this issue Feb 25, 2023 · 9 comments
Closed

proposal: slices: add difference function #58730

cuishuang opened this issue Feb 25, 2023 · 9 comments

Comments

@cuishuang
Copy link
Contributor

cuishuang commented Feb 25, 2023

There are many scenarios where it is necessary to obtain the difference of two slices. At present, the more common method is to create a new utils package in the project and write the method implementation in it. Now that the Go standard library has a new slices package, it is recommended to add an API:

func Difference[E comparable](s1, s2 []E) []E {
	var result []E
	s2len := len(s2)
	s1len := len(s1)
	if s2len == 0 {
		return s1
	}
	s2Map := make(map[E]bool, s2len)
	for i := 0; i < s2len; i++ {
		el := s2[i]
		s2Map[el] = true
	}
	for i := 0; i < s1len; i++ {
		element := s1[i]
		if _, ok := s2Map[element]; !ok {
			result = append(result, element)
		}
	}
	return result
}

Similar as golang/exp#50

The full implementation golang/exp#60

@fzipp
Copy link
Contributor

fzipp commented Feb 25, 2023

This sounds like an operation that would suit a set datatype better than slices.

@seankhliao seankhliao changed the title proposal: Slices: add Difference function proposal: slices: add difference function Feb 26, 2023
@seankhliao
Copy link
Member

This seems to have a very specific idea of "difference".
Slices aren't a set of objects, they also include ordering, and items can be duplicated.
How do you justify using this definition of difference vs others?

@DeedleFake
Copy link

If this isn't going to preserve ordering, I see no reason that this shouldn't just be handled, eventually, as something like

set1 := set.New(slice1...)
diff := set1.Sub(set.New(slice2)...)
diffslice := diff.Slice()

That's not much more difficult, is more obvious about what it's doing and all the implicit allocations, and gives the caller significantly more control.

@jimmyfrasche
Copy link
Member

This is filter of s1 but using a set provided as a slice in s2 instead of a predicate function.

@rsc
Copy link
Contributor

rsc commented Mar 8, 2023

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@dsnet
Copy link
Member

dsnet commented Mar 8, 2023

In addition to the good arguments about this really being a set operation...

For a function named Difference, I would have expected it to produce an edit script, which is essentially a sequence of insert and delete operations that converts the left argument into the right argument. But such a function is probably too complex to live in the slices package and should be a different package.

@rsc
Copy link
Contributor

rsc commented Mar 15, 2023

Based on the discussion above, this proposal seems like a likely decline.
— rsc for the proposal review group

@cuishuang
Copy link
Contributor Author

除了关于这真的是一个集合操作的好的论据之外......

对于名为 的函数Difference,我希望它生成一个编辑脚本,它本质上是一系列插入和删除操作,将左参数转换为右参数。但是这样的功能可能太复杂了,不能放在slices包中,应该放在不同的包中。

This seems like a better proposal. Thanks

@rsc
Copy link
Contributor

rsc commented Mar 29, 2023

No change in consensus, so declined.
— rsc for the proposal review group

@rsc rsc closed this as completed Mar 29, 2023
@golang golang locked and limited conversation to collaborators Mar 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants