Search code examples
c++c++17stdvector

Easiest way to combine 3 std::vector into a temporary single std::vector?


I have seen this discussion (Concatenating two std::vectors) but it concerns combining (as in moving) two std::vector arrays.


I have three std::vectors and I am using C++17:

  1. m_mapHist[m_eHistAssign][strName]
  2. m_mapScheduleHist[m_eHistAssign][strName]
  3. m_mapScheduleFutureHist[m_eHistAssign][strName]

Each vector is of type std::vector<COleDateTime>. I don't want to change these vectors. Instead, I want to combine them (copy I guess) into a temporary single vector, so I can pass just the one vector to another class for processing.

At the moment I am doing this manually through iteration:

std::vector<COleDateTime> vecAssignmentDate;

// Past items from the history database
if (m_mapHist[m_eHistAssign].find(strName) != m_mapHist[m_eHistAssign].end())
{
    for (const auto& historyItemDate : m_mapHist[m_eHistAssign][strName])
    {
        vecAssignmentDate.push_back(historyItemDate);
    }
}

// Past items on the active schedule
if (m_mapScheduleHist[m_eHistAssign].find(strName) != m_mapScheduleHist[m_eHistAssign].end())
{
    for (const auto& historyItemDate : m_mapScheduleHist[m_eHistAssign][strName])
    {
        vecAssignmentDate.push_back(historyItemDate);
    }
}

// Future items (both on the active schedule and in the history database)
if (m_mapScheduleFutureHist[m_eHistAssign].find(strName) != m_mapScheduleFutureHist[m_eHistAssign].end())
{
    for(const auto &historyItemDate : m_mapScheduleFutureHist[m_eHistAssign][strName])
    {
        vecAssignmentDate.push_back(historyItemDate);
    }
}

Is there an easier way to create this temporary vector?


Solution

  • You may use boost::join. Example:

    std::vector<COleDateTime> v1;
    std::vector<COleDateTime> v2;
    std::vector<COleDateTime> v3;
    std::vector<COleDateTime> result;
    
    result = boost::join(boost::join(v1, v2), v3);
    

    Since c++17 the standard also have a std::merge util function:

    std::vector<COleDateTime> v1;
    std::vector<COleDateTime> v2;
    std::vector<COleDateTime> v3;
    std::vector<COleDateTime> result;
    
    std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result));
    std::merge(v3.begin(), v3.end(), result.begin(), result.end(), std::back_inserter(result));
    

    Differences between std::merge and std::copy

    from cplusplus.com/reference/algorithm/merge/ std::merge:

    Combines the elements in the sorted ranges [first1,last1) and [first2,last2), into a new range beginning at result with all its elements sorted.

    from cplusplus.com/reference/algorithm/copy/ std::copy:

    Copies the elements in the range [first,last) into the range beginning at result..

    So it depends on what you want to achieve.