YoYoGames / GameMaker-Bugs

Public tracking for GameMaker bugs
22 stars 8 forks source link

array_difference #2768

Open meseta opened 10 months ago

meseta commented 10 months ago

Is your feature request related to a problem?

we have array_union and array_intersection, however we don't have array_difference. It's a useful set-theory function that returns values that are in one array but not the other.

Set theory in general is very useful for game dev, but to give a more specific example, let's say I have a square region of the world where characters can walk in and out of. And at any given frame, I want to know who just walked in, and who just walked out.

A good way to do this is to create an array of characters who are in the square, let's say A is the array of characters in the square from last frame, and B is the array of characters in the square this frame. We can use the various array/set theory functions in this way:

Describe the solution you'd like

I'd like a function array_difference(A, B) that returns a new array containing only values that were in the first argument that aren't in the second argument.

Describe alternatives you've considered

array_difference could be implemented using:

function array_difference(A, B) {
  return array_copy_while(A, method({B: B}, function(el) { return !array_contains(B, el); }));
}

But this is quite a nasty looking thing

Additional context

No response

Delfos1 commented 9 months ago

Great idea, but I do feel like "difference" would result in a new array containing all elements except the ones that are shared. (the opposite of array_intersection) I feel like this should be called "substract" instead.

It would be great that the manual/tooltips inside GM would show graphics like the one you did. It's very intuitive and fast to convey information with it.

meseta commented 9 months ago

An array containing all elements except the ones that are shared is commonly called the "symmetric difference"

Set theory functions appear in many other languages, and the function I described is consistently named "difference"; they also have the one you described, and is named "symmetric difference". for example: Javascript (proposed) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/difference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/symmetricDifference

C++: https://cplusplus.com/reference/algorithm/set_difference/ https://cplusplus.com/reference/algorithm/set_symmetric_difference/

and Python: https://www.programiz.com/python-programming/methods/set/difference https://www.programiz.com/python-programming/methods/set/symmetric_difference

While "subtract" isn't an inaccurate description, and operator overloading in languages like Python let you do A-B to achieve a set-difference, I do still suggest using the same naming convention as other languages as well as the formal mathematical definition for the operation, since there's a strong precedent for it

As an aside, we should also have an array_symmetric_difference() function, since that's occasionally useful too.

mistletoe commented 9 months ago

Plus 1. I have wanted to do this before, and it's clunky to achieve in GML right now.