Jump to content
Tankbuster

comparing equal, but disordered arrays

Recommended Posts

I want to test for arrays that are the same length and contain the same data, but might be in a different order.

 

I've come up with this, but want to run it by you chaps to see if there's an edge case that I might have missed.


 

_array1 = ["beer", "steak", "girls", "gaming", "chocolate"]

_array2 = ["chocolate", "gaming", "girls", "steak" , "beer"]

 

I want to be able to get a true out of comparing these arrays. Here's what I came up with;

 

_result = array1 isequalto (array1 select {_x in array2}) 

 

But I'm getting the dreaded 'generic error in expression'. Am I on the right track?

 

Share this post


Link to post
Share on other sites
1 minute ago, Schatten said:

@Tankbuster, another solution:


(_array1 sort true) isEqualTo (_array2 sort true)

Will this work with objects, specifically road pieces?

Share this post


Link to post
Share on other sites
2 minutes ago, Tankbuster said:

Will this work with objects, specifically road pieces?

No https://community.bistudio.com/wiki/sort

And the arrayIntersect variant should be faster anyway.

though arrayIntersect will fail if you have duplicates in one of the arrays.
But

(count (_array1 arrayIntersect _array2)) == (count (_array1 arrayIntersect _array1))

can solve that

  • Like 2

Share this post


Link to post
Share on other sites
17 minutes ago, Tankbuster said:

I want to test for arrays that are the same length and contain the same data, but might be in a different order.

 

I've come up with this, but want to run it by you chaps to see if there's an edge case that I might have missed.


 


_array1 = ["beer", "steak", "girls", "gaming", "chocolate"]

_array2 = ["chocolate", "gaming", "girls", "steak" , "beer"]

 

I want to be able to get a true out of comparing these arrays. Here's what I came up with;

 


_result = array1 isequalto (array1 select {_x in array2}) 

 

But I'm getting the dreaded 'generic error in expression'. Am I on the right track?

 

 

Not getting your error, returns true just fine, make sure you're correctly writing either array1 or _array1 and don't forget the semicolons, heh.

The arrayIntersect solution posted by @Schatten seems to be the best solution.

 

Cheers

Share this post


Link to post
Share on other sites
9 minutes ago, Dedmen said:

No https://community.bistudio.com/wiki/sort

And the arrayIntersect variant should be faster anyway.

though arrayIntersect will fail if you have duplicates in one of the arrays.
But


(count (_array1 arrayIntersect _array2)) == (count (_array1 arrayIntersect _array1))

can solve that

There won't be duplicates in the array, but I'll use this anyway.

Share this post


Link to post
Share on other sites
15 minutes ago, Dedmen said:

though arrayIntersect will fail if you have duplicates in one of the arrays.

But


(count (_array1 arrayIntersect _array2)) == (count (_array1 arrayIntersect _array1))

can solve that

_array1 = ["beer", "beer", "steak", "girls", "gaming", "chocolate"];
_array2 = ["chocolate", "gaming", "gaming", "girls", "steak", "beer"];

_result1 = (count (_array1 arrayIntersect _array2)) == (count _array1); // false
_result2 = (count (_array1 arrayIntersect _array2)) == (count (_array1 arrayIntersect _array1)); // true

But, as we can see, arrays are not equal!

  • Like 1

Share this post


Link to post
Share on other sites

Well... Unfortunately, my solution will fail with these arrays:

_array1 = ["beer", "beer", "steak", "girls", "gaming", "chocolate"];
_array2 = ["chocolate", "gaming1", "gaming", "girls", "steak", "beer"];

_result = (count (_array1 arrayIntersect _array2)) == (count _array1); // true, because "_array1 arrayIntersect _array2" returns array with 6 elements: ["beer", "steak", "girls", "gaming", "chocolate", "gaming1"]

Seems, this is the best solution for sortable arrays. If arrays contain non sortable elements (e. g., objects), you can try this solution:

((_array1 apply {str _x}) sort true) isEqualTo ((_array2 apply {str _x}) sort true)

 

13 hours ago, pierremgi said:

(_aa arrayIntersect _bb) isEqualTo _bb

Unfortunately, this solution can fail in case if order of elements of returned by "_aa arrayIntersect _bb" array differs with one of _bb.

  • Like 1

Share this post


Link to post
Share on other sites
4 hours ago, Schatten said:

Unfortunately, this solution can fail in case if order of elements of returned by "_aa arrayIntersect _bb" array differs with one of _bb.

 

Did you meet an example? I shuffled both arrays and that worked each time.

Share this post


Link to post
Share on other sites

@pierremgi, sorry, I was wrong -- have noticed that if arrays have same length then order of elements of returned by arrayIntersect command array match with one of second array:

_array1 = ["beer", "steak", "girls1", "gaming", "chocolate"];
_array2 = ["chocolate", "gaming", "girls", "steak", "beer"];

_result = _array1 arrayIntersect _array2; // ["chocolate", "gaming", "steak", "beer"]

Otherwise, if arrays have not same length, then order of elements match with one of first array:

_array1 = ["beer", "steak", "girls1", "gaming", "chocolate"];
_array2 = ["chocolate", "gaming", "steak", "beer"];

_result = _array1 arrayIntersect _array2; // ["beer", "steak", "gaming", "chocolate"]

Looks like your solution is the best!

  • Like 3

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×