-1

The following script is working fine. But need to add one more item in array without built-in function. Is it possible to do without Resize() ?

string[] data = {"item-1", "item-2"};
Array.Resize(ref data, 3);
data[2] = "item-3";
foreach(string i in data) {
  Console.WriteLine(i);
}
Drkawashima
  • 8,837
  • 5
  • 41
  • 52
Billu
  • 2,733
  • 26
  • 47
  • 2
    No, it's not possible to resize an array without `Resize`. You could copy to a _new_ array of the new size, but it's not clear what constraints you have. – D Stanley Nov 29 '22 at 19:46
  • 1
    Well, you could create a new array with a greater length and copy the items to that array. Generally this is how lists work "under the hood" – AchoVasilev Nov 29 '22 at 19:46
  • 2
    *"need to add one more item in array without built-in function"* - Define "without built-in function[s]". You could go so far as to use a `List` and only output it as an array when specifically an array is needed. (If an actual array is needed at all and not just something enumerable.) But all of that uses "built-in functions". I'd struggle to write *any* meaningful code which doesn't use "built-in functions" somewhere. It's not clear to me what problem you're trying to solve. – David Nov 29 '22 at 19:48
  • 1
    FYI dotnet code is open source so you could look at how it is done, and from there do you own version of it here: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Array.cs#L42 – Rand Random Nov 29 '22 at 19:52

3 Answers3

3

No. Arrays are fixed size, so the only way to add more stuff to them is to resize them.

If you have a scenario where you need to add a dynamic number of elements, use List<T> instead.

julealgon
  • 7,072
  • 3
  • 32
  • 77
  • 1
    Op needs to do this without any built-in language features like List – Charles Yang Nov 29 '22 at 19:48
  • @CharlesYang, `List` is a type, not a language feature or built-in function. – Olivier Jacot-Descombes Nov 29 '22 at 21:12
  • 1
    Built-in data structure, tomato-tomato – Charles Yang Nov 29 '22 at 21:39
  • Upvoted. This is the correct answer to the question "Can I resize an existing array without built-in-language features?" The answer is NO. Impossible to resize an array without `Resize()`. (but of course it's possible to do something different like creating a new array) – Drkawashima Dec 01 '22 at 21:40
  • @Drkawashima - rather contradict yourself there, first you say you need resize method and than go ahead and state an alternative to using the resize method… - So, the answer is yes, you do NOT have to use the `Resize` method – Rand Random Dec 03 '22 at 00:52
  • @RandRandom it's not a contradiction because the alternative it to not use an array in the first place. – julealgon Dec 03 '22 at 19:12
  • @julealgon - wasn’t talking about the answer but the comment of the person I tagged were the alternative is `but of course it's possible to do something different like creating a new array` – Rand Random Dec 03 '22 at 21:38
  • 1
    @julealgon My thinking is that given the specific question "Can I add another item to this specific Array" the specific answer is "no". Since the question mentioned built-in-methods I figured it was asking about resizing the specific array, and not asking for alternative ways of creating new variables, copying values or using different types – Drkawashima Dec 05 '22 at 12:04
2

Assuming you're trying to increase the size of an array without any built-in libraries or data structures, you just need to create a new larger array, copy the old elements, then add your new element.

string[] data = {"item-1", "item-2"};
string[] newData = new string[data.Length + 1];

int i;
for (i = 0; i < data.Length; i++) {
    newData[i] = data[i];
}
newData[i] = "item-3";
Console.WriteLine(newData[2]);
Billu
  • 2,733
  • 26
  • 47
Charles Yang
  • 330
  • 2
  • 10
2

The short answer is no. But if you want you can always implement a logic that does the resizing. You could do something like this implementation of a List:

public class List<T> : IAbstractList<T>
{
    private const int DEFAULT_CAPACITY = 4;
    private T[] _items;

    public List()
        : this(DEFAULT_CAPACITY) {
    }

    public List(int capacity)
    {
        if (capacity < 0)
        {
            throw new ArgumentOutOfRangeException(nameof(capacity));
        }

        this._items = new T[capacity];
    }

    public T this[int index]
    {
        get
        {
            this.ValidateIndex(index);
            return this._items[index];
        }
        set
        {
            this.ValidateIndex(index);
            this._items[index] = value;
        }
    }

    public int Count { get; private set; }

    public void Add(T item)
    {
        this.GrowIfNecessary();

        this._items[this.Count++] = item;
    }

    public bool Contains(T item)
    {
        for (int i = 0; i < this.Count; i++)
        {
            if (this._items[i].Equals(item))
            {
                return true;
            }
        }

        return false;
    }

    public int IndexOf(T item)
    {
        for (int i = 0; i < this.Count; i++)
        {
            if (this._items[i].Equals(item))
            {
                return i;
            }
        }

        return -1;
    }

    public void Insert(int index, T item)
    {
        this.ValidateIndex(index);
        this.GrowIfNecessary();

        for (int i = this.Count - 1; i > index; i--)
        {
            this._items[i] = this._items[i - 1];
        }

        this._items[index] = item;
        this.Count++;
    }

    public bool Remove(T item)
    {
        var index = this.IndexOf(item);
        if (index == - 1)
        {
            return false;
        }

        this.RemoveAt(index);
        return true;
    }

    public void RemoveAt(int index)
    {
        this.ValidateIndex(index);
        for(int i = index; i < this.Count - 1; i++)
        {
            this._items[i] = this._items[i + 1];
        }

        this._items[this.Count - 1] = default;
        this.Count--;
    }

    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < this.Count; i++)
        {
            yield return this._items[i];
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
        => this.GetEnumerator();

    private void ValidateIndex(int index)
    {
        if (index < 0 || index >= this.Count)
        {
            throw new IndexOutOfRangeException(nameof(index));
        }
    }

    private void GrowIfNecessary()
    {
        if (this.Count == this._items.Length)
        {
            var array = new T[this.Count * 2];
            Array.Copy(this._items, array, this._items.Length);

            this._items = array;
        }
    }
}

The above sample code can give you ideas about implementing other methods that need array resizing as well.

AchoVasilev
  • 454
  • 5
  • 15