开发者

C++ - Sort multidimensional vector by its contained object property

I've got a bidimensional array of objects (a 2D vector containing GridCell instances) as in here:

typedef vector<GridCell> CellArray;
typedef vector<CellArray> TwoDCellArray;
TwoDCellArray CellArr2D;

I am currently drawing all the cells like this:

for (int i = 0; i < rows; i++){
    for (int j = 0; j < cols; j++){
        CellArr2D[i][j].draw()
    }
}

However, I've got a depth problem and I should draw the instances depending on its size (size property, CellArr2D[i][j].size).

What should I do to sort this array without changing it's i,j values? Copying all the objects to a secondary array and sort that one? And more imporntant, hence this post... how can I开发者_运维问答 sort an Array (Vector) by it's contained object property?

Thanks in advance.


Create a vector of pairs (i,j) and sort it by size property.

typedef std::pair<int, int> int_pair_t;
typedef std::vector< int_pair_t > size_index_t;

namespace {
struct sort_helper {
    sort_helper( const TwoDCellArray& arr ) : arr_(arr) {}      
    bool operator()( const int_pair_t& ind1, const int_pair_t& ind2 ) { 
      return arr_[ind1.first][ind1.second].size > arr_[ind2.first][ind2.second].size; 
    }
private:
    const TwoDCellArray& arr_;
};

struct draw_helper {
    draw_helper( TwoDCellArray& arr ) : arr_(arr) {}        
    void operator()( const int_pair_t& ind ) { 
        arr_[ind.first][ind.second].draw();
    }
private:
    TwoDCellArray& arr_;
};
}

void some_func()
{
    // initialize helper array of indices
    size_index_t index;
    index.reserve( rows*cols );
    for ( int i = 0; i < rows*cols; ++i )
        index.push_back( make_pair( i/cols%rows, i%cols ) );

    // sort according to the `size` field
    std::sort( index.begin(), index.end(), sort_helper( CellArr2D ) );

    // draw
    std::for_each( index.begin(), index.end(), draw_helper( CellArr2D ) );
}


Use std::sort and supply a custom comparison function object to sort by a user-defined property or other relation.

As for how it should be sorted, if you want to sort it but not change it, then you will have to copy the array. The best way to do this is store your GridCells on the heap and store smart pointers to them in the vectors. This way, sorting and copying them will involve less overhead.


You can put references in a secondary array and sort that one:

struct CellRef
{
  CellRef(GridCell& cell) : m_c(cell) {}
  bool operator<(const CellRef& r) const { return m_c.size < r.m_c.size; }
  GridCell& data() { return m_c; }
private:
  GridCell& m_c;
};

vector<CellRef> refs;
for (int i = 0; i < rows; i++){
    for (int j = 0; j < cols; j++){
        refs.push_back(CellArr2D[i][j]);
    }
}
std::sort(refs.begin(), refs.end());
for(vector<CellRef>::iterator it=refs.begin(), end=refs.end(); it!=end; ++it)
  it->data().draw();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜