[Closed] is there any funcation in maxscript for arrays Subtraction
hi guys, is there any funcation in maxscript can do Subtraction for two arrays , like
tt = #(“aa”,“bb”,“cc”)
dd = #(“aa”,“bb” )
tt – dd = #(“cc” )
:shrug:
thanks!
fn SubAB AA BB =
(
for i = 1 to BB.count do if finditem AA BB[i] != 0 do deleteitem aa (finditem AA BB[i])
AA
)
tt = #("aa","bb","cc")
dd = #("aa","bb" )
cc = subAB (deepcopy tt) dd
If you don’t use deepcopy then tt will become #(“cc”)
fn SubAB AA BB =
(
for i = 1 to BB.count do
(
local f = (finditem AA BB[i])
if f != 0 do deleteitem aa f
)
AA
)
tt = #("aa","bb","cc")
dd = #("aa","bb" )
cc = subAB (deepcopy tt) dd
Can it be any quicker Denis?
absolutely… one finditem is two times quicker than two finditems
maybe it will be faster to re-collect an array like:
for i in A where finditem B i == 0 collect i
probably it will…
Yeah you wouldn’t then need to do a DeepCopy either…
fn SubAB AA BB = for i in AA where finditem BB i == 0 collect i
tt = #("aa","bb","cc")
dd = #("aa","bb" )
cc = subAB tt dd
might not be very efficient when the array size increases as it has to parse the whole array every time (though saying that I don’t have anything better, just sticking my nose in ).
scratch that don’t know what i’m talking about
Hmm might it have something to do with multiple occurances in the array?
yeah… that’s the question. what do we do with not unique elements…
in short
#(a,b,b,c) – #(b) has to be #(a,c) or #(a,b,c)
we have to pick the only one…
I thought a little more and found for myself the most correct solution for array subtraction…
follow my logic:
when we add array we add elements to the end, so when we subtract we also have to subtract from the end
add and subtract functions have to be ‘symmetrical’. if add adds something the subtract has to remove the same
max’s add function doesn’t change destination array, so subtract doesn’t do it either
does it all make sense?
so the function below is only one that meets all my conditions.
fn subtractArray a b =
(
a = copy a #nomap
b = copy b #nomap
for k = a.count to 1 by -1 while b.count > 0 where (i = finditem b a[k]) != 0 do
(
deleteitem a k
deleteitem b i
)
a
)
a = #("a","b","c","b","c","b")
b = #("c","b","b")
c = subtractArray a b
a
b
c
Surely that’s a question of design as much as coding, though? Afterall, the original post doesn’t suggest whether duplicates should be removed. I can see an instance where you’d want…
AA = #(“three”,“blind”,“mice”,“three”)
BB = #(“three”,“blind””)
CC = AA – BB
CC to be #(“mice”) and another where you’d want it to be #(“mice”,“three”).
Edit: Beaten above! I guess you’d need a switch passed to the function along with the two arrays.
This is the function I use for subtracting arrays –
fn SubtractArray Input1:#() Input2:#() =
(
if (Input1 != undefined and Input2 != undefined) then
(
Result = #() -- Initial Array
for i in Input1 do
(
ArrayItem = finditem Input2 i -- Find second array's element
if ArrayItem == 0 then append Result i -- If element does not exist then add to array
) -- Subtract arrays
Result
) -- If inputs exist
)
And here’s a function for multiplication –
fn DifferenceArray Input1:#() Input2:#() =
(
if (Input1 != undefined and Input2 != undefined) then
(
Result = #() -- Initial selection
for i in Input1 do
(
ArrayItem = finditem Input2 i -- Find second array's element
if ArrayItem != 0 then append Result i -- If element exists then add to array
) -- Intersect arrays
Result
) -- If inputs exist
)