How to compare (and remove in) one custom type list with a vector3 list?

I have a HashSet, a List and a class.

Relayhash contains a set of Vector3 variables. Used as a list for input, usually one variable is picked either randomly or via another rule.

tempList To temporarily store vector3 variables for comparison.

BuildList contains a set of custom class types (moduleclass) and serves as the destination of selected variables.Here, I would like to find out if it contains a certain variable (posv3).

  public class moduleClass
    {
        public int step { get; set; }
        public int modID { get; set; }
        public string modType { get; set; }
        public int typeint { get; set; }
        public Vector3 posv3 { get; set; }
    }

I would like to find out if relayhash contains a Vector that is already in BuildList. If true, then the found Vector3(s) needs to be removed from ‘relayHash’. Then the values of the relayhash (Hashset) can be copied to the tempList (List) to enable random selection:

Vector3 randomV3 = tempList[Random.Range(0, relayhash.Count)];

The main issue is now that it’s not possible to remove a found Vector from the ‘relayhash’. For example:

var foundVectors = relayhash.Intersect(BuildList.Select(x => x.posv3));

relayhash.Remove(foundVectors);

results in:

error CS1503: Argument 1: cannot convert from 'System.Collections.Generic.IEnumerable<UnityEngine.Vector3>' to 'UnityEngine.Vector3'

So my question remains: how can I compare a vector3 between two lists- BuildList and relayhash- (one as a vector3 between custom datatypes and the other list vector3 only) and if a duplicate is found, remove it from the second list?

Alternatively, the script may select a random vector3 from the relayhash, and if not already in BuildList, add to it.

Thanks for reading.
ps I received helpful answers here but it didn’t work.

have you tryed to put your found vectors in a list instead of a “var” ?

   List<Vector3> foundVectors = relayhash.Intersect(BuildList.Select(x => x.posv3));

or something like

relayhash.Remove((Vector3)foundVectors);

writing from the site, cant test it

Thanks @Terraya

These are indeed interesting options and I tried variations before of what you wrote. But unfortunately it delivers the same errors:

For the first line:

error CS0266: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<UnityEngine.Vector3>' to 'System.Collections.Generic.List<UnityEngine.Vector3>'. An explicit conversion exists (are you missing a cast?)

and the second:

error CS0030: Cannot convert type 'System.Collections.Generic.List<UnityEngine.Vector3>' to 'UnityEngine.Vector3'

Thanks for the help anyway!

sorry for that quick and small answers before,
i was in the train and had to rush,

so actualy there is a posibility to cast your hashmap result into a vector3 list,
if not casting, then at least put it in a list,

but before you try all that stuff,
have you debug.logt your variable “foundvectors” ?

check first whats exactly inside, and then let me know :slight_smile:

Thanks!

Using

List<Vector3> foundVectors = relayhash.Intersect(BuildList.Select(x => x.posv3));

results in error:

error CS0266: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<UnityEngine.Vector3>' to 'System.Collections.Generic.List<UnityEngine.Vector3>'. An explicit conversion exists (are you missing a cast?)

So the foundVectors cannot be read (the program won’t start).

Instead, if i use:

var foundVectors = relayhash.Intersect(BuildList.Select(x => x.posv3));

Debug.Log foundvectors results in:

foundvectors:System.Linq.Enumerable+<IntersectIterator>d__77`1[UnityEngine.Vector3]

Without errors. But then if I try for example this:

 tempList.Add(foundVectors);

…again, it results in:

error CS1503: Argument 1: cannot convert from 'System.Collections.Generic.IEnumerable<UnityEngine.Vector3>' to 'UnityEngine.Vector3'

.Intersect() returns a collection of Vectors3 (of type IEnumerable). Your relayHash function does not contain any IEnumerable's (it just contains Vector3’s), so you can’t remove the result from relayHash.

You have to iterate over the result and remove each vector.

Try this, it should also do your tempList at the same time:

tempList = relayhash.Intersect(BuildList.Select(x => x.posv3)).ToList();
foreach(var vector in tempList) relayHash.Remove(vector);

Thanks @bobisgod234 !

Looks promising and at least no errors. Will experiment a bit and report back!

It worked, but for some reason the tempList always returnes empty. Perhaps because of the mixed type, I don’t know.

I ended up using this instead, the scripts works for now.

 foreach (moduleClass tempvar in BuildList)
        {
            Vector3 tempv3 = tempvar.posv3;
            if (relayhash.Contains(tempv3))
            {
                // remove from relayhash
                relayhash.Remove(tempv3);
                //Debug.Log("vector removed : ");
            }
        }

        foreach (Vector3 tempv in relayhash)
        {
            tempList.Add(tempv);
        }

I’m going to keep your suggested code however and see if it can be applied since it looks a lot cleaner than the two foreach loops.

Thanks a lot!