Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi! I am working on creating a big project and need some help with two functions. I need to create a function that does the same thing as Linq, Append and Distinct without using Linq or Lists. If you are able to help me out I would greatly appreciate it!

Append: Add a object to the end of a Array.
Distinct: Remove duplicates and nulls/empties from Array.

Thanks in advance!!

What I have tried:

Append Code:
C#
private GameObject[] AddtoArray(GameObject[] garray, GameObject objg)
    {

        GameObject[] newarray = new GameObject[1] { objg };
        GameObject[] returnarray = new GameObject[garray.Length + 1];
        returnarray.CopyTo(garray, 0);
        returnarray.CopyTo(newarray, returnarray.Length);


        return returnarray;
    }


Distinct Code(Unfinished):
C#
private GameObject[] Distinct(GameObject[] ourarray)
    {
        foreach(GameObject obj in ourarray)
        {
            int amountfound = 0;
            GameObject currentobj = obj;
                foreach(GameObject OBJJ in ourarray)
            {
                if(OBJJ == obj)
                {
                    amountfound ++;
                    if (amountfound == 1)
                    {
                        continue;
                    }
                }
            }
        }





        return ourarray;
    }
Posted
Updated 31-Oct-22 1:10am
Comments
PIEBALDconsult 28-Oct-22 14:50pm    
If you need distinct, maybe use a Hashset instead?
Jean Ferre 29-Oct-22 9:23am    
Why is List/LINQ incompatible with the game? What did you try to do? Could you share the code that doesnt compile, and tell us what error message you get?
Mae Spencer 29-Oct-22 13:42pm    
I am creating something for VRChat and VRChat doesn't allow custom scripts. But they do allow people to use their own compiler. But it isn't compatible with Lists or Linq at the moment

That's a really inefficient way to do it: a List maintains an internal array which when it it full it allocates and copies into an new array twice the size. That's way, way more efficient than what you are doing - have a look here and see how careful you have to be with Lists, never mind your version: List<T> - Is it really as efficient as you probably think?[^]

I would strongly suggest that you think again why you really want to use an array if you are planning on expanding it, instead of a List. You could be giving yourself a lot of problems - including performance problems - when your game gets busy ...
 
Share this answer
 
Comments
Mae Spencer 28-Oct-22 14:40pm    
I need to use Arrays since Lists are not compatible with the program I am making this for.
OriginalGriff 28-Oct-22 14:47pm    
Then either change the program, or use the ToArray method when you need to - what you are trying to do is going to cause you a lot of problems later.

I know it's difficult to change stuff you written, but it's a much better solution that bodging round the shortcomings you have engineered into your app.
Mae Spencer 28-Oct-22 20:38pm    
Its 100% possibly to change the stuff I've already written but this won't compile for the game I'm making it for if the code contains Lists or Linq in anyway. I originally wrote it with Linq and lists but later learned they are completely incompatible with the game. So I am forced to do it without. Please lmk how I would go about this?
First up, your AddToArray code is wrong. You copy the empty returnarray to the passed-in garray array. You then copy the empty returnarray to the single-element newarray array. Both attempts to copy will result in an ArgumentException:
ArgumentException:
Destination array was not long enough. Check destIndex and length, and the array's lower bounds.
You need to reverse the direction of your copy operation. And you can simplify your code while you're at it:
C#
private T[] AddToArray<T>(T[] garray, T objg)
{
    Array.Resize(ref garray, garray.Length + 1);
    garray[garray.Length - 1] = objg;
    return garray;
}
The Array.Resize[^] method takes care of allocating a new array of the desired size and copying the values from the old array to the new array.

For the Distinct method, I'd suggest something like this:
C#
private T[] Distinct(T[] ourarray)
{
    if (ourarray is null || ourarray.Length == 0)
    {
        return ourarray;
    }
    
    HashSet<T> distinctValues = new HashSet<T>();
    bool[] itemsToRemove = new bool[ourarray.Length];
    int numberOfItemsToRemove = 0;
    
    for (int index = 0; index < ourarray.Length; ++index)
    {
        if (distinctValues.Add(ourarray[index])) continue;
        itemsToRemove[index] = true;
        ++numberOfItemsToRemove;
    }
    
    if (numberOfItemsToRemove == 0) 
    {
        // All items in the source array are distinct:
        return ourarray;
    }
    
    int resultLength = ourarray.Length - numberOfItemsToRemove;
    T[] result = new T[resultLength];
    int resultIndex = 0;
    
    for (int index = 0; index < ourarray.Length; index++)
    {
        if (itemsToRemove[index]) continue;
        result[resultIndex] = ourarray[index];
        ++resultIndex;
    }
    
    return result;
}

If the version of the .NET Framework you're using doesn't support the HashSet<T> type, then it's seriously out-of-date. That class has been around since .NET Framework 3.5, released back in 2007.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900