concatenationvclc++builder-10.3-riotstringdynarray

How to concatenate two TStringDynArray?


Is there a way to concatenate the content of one TStringDynArray to another TStringDynArray?

//First TStringDynArray
Item1
Item2
Item3

//Second TStringDynArray
ItemA
ItemB
ItemC

//Result after concatenate
Item1
Item2
Item3
ItemA
ItemB
ItemC

Solution

  • Not directly, as System::DynamicArray does not provide concatenation features in C++. So you would need to create a 3rd TStringDynArray, size it to the sum of the sizes of the 2 arrays, and individually copy each String from the 2 arrays into the 3rd array (String is reference-counted, so you can't just copy bytes with memcpy() or equivalent, like you can with arrays of trivial types), eg:

    TStringDynArray Arr1;
    // fill Arr1 as needed...
    
    TStringDynArray Arr2;
    // fill Arr2 as needed...
    
    TStringDynArray MergedArr;
    MergedArr.Length = Arr1.Length + Arr2.Length;
    int idx = 0;
    
    for(int i = 0; i < Arr1.Length; ++i) {
        MergedArr[idx++] = Arr1[i];
    }
    
    for(int i = 0; i < Arr2.Length; ++i) {
        MergedArr[idx++] = Arr2[i];
    }
    
    // use MergedArr as needed...
    

    Alternatively (C++Builder 10.1 Berlin and later):

    #include <algorithm>
    
    TStringDynArray Arr1;
    // fill Arr1 as needed...
    
    TStringDynArray Arr2;
    // fill Arr2 as needed...
    
    TStringDynArray MergedArr;
    MergedArr.Length = Arr1.Length + Arr2.Length;
    std::copy(Arr1.begin(), Arr1.end(), MergedArr.begin());
    std::copy(Arr2.begin(), Arr2.end(), MergedArr.begin() + Arr1.Length);
    
    // use MergedArr as needed...
    

    In the Clang-based compilers, you can take this a step further by using some variadic template functions to help you concatenate as many input TStringDynArray arrays as you want, eg:

    #include <algorithm>
    
    int ArrLength()
    {
        return 0;
    }
    
    template<typename... Ts>
    int ArrLength(TStringDynArray &arr, Ts&... others)
    {
        return arr.Length + ArrLength(others...);
    }
    
    void ArrCopy(TStringDynArray::iterator dst)
    {
    }
    
    template<typename... Ts>
    void ArrCopy(TStringDynArray::iterator dst, TStringDynArray &arr, Ts&... others)
    {
        std::copy(arr.begin(), arr.end(), dst);
        ArrCopy(dst + arr.Length, others...);
    }
    
    template<typename... Ts>
    TStringDynArray ArrMerge(TStringDynArray &arr, Ts&... others)
    {
        TStringDynArray res;
        res.Length = ArrLength(arr, others...);
        ArrCopy(res.begin(), arr, others...);
        return res;
    }
    
    ...
    
    TStringDynArray Arr1;
    // fill Arr1 as needed...
    
    TStringDynArray Arr2;
    // fill Arr2 as needed...
    
    TStringDynArray MergedArr = ArrMerge(Arr1, Arr2/*, Arr3, Arr4, ...*/);
    // use MergedArr as needed...