在一個小應用程序中,我一直使用std::vector
的std::vector<std::string>
臨時存儲 某些數據(從非SQL數據庫中提取),然後將其處理並上傳到SQL數據庫。不幸的是,我從中提取數據的API不一定以查詢指定的順序返回字段; 例如如果我的查詢請求領域x, y, z
,該數據可能會返回爲y, x, z
,或z, y, x
,等等......顯然 這是有問題的,因爲如果目標SQL表的列x, y, z
,然後插入數據需求 反映這一點。爲了說明這個隨機場排序,我寫了一個小函數,它取(1)由API返回的輸入數據; 和(2)代表所需列排序的std::vector<std::string>
,如SQL表中定義的那樣 - 並且 相應地重新排序每個子向量的元素。由於輸入數據的第一行是場 名的載體,我能夠把它正確有序向量與該和確定各個子矢量應該 重新排序:基於輸入向量對向量進行重新排序
void fix_order(std::vector<std::vector<std::string>>& data, const std::vector<std::string>& correct) {
std::size_t width = data[0].size();
std::vector<int> order_idx(width);
for (std::size_t i = 0; i < width; i++) {
std::string tmp(data[0].at(i));
auto pos = std::find(correct.begin(), correct.end(), tmp);
order_idx[i] = std::distance(correct.begin(), pos);
}
for (std::size_t i = 0; i < data.size(); i++) {
if (!data[i].empty()) {
std::vector<std::string> q(width);
for (unsigned int j = 0; j < width; j++) {
int new_pos = order_idx[j];
q[new_pos] = data[i].at(j);
}
std::swap(data[i], q);
}
}
}
在行動,如果輸入的數據字段大小順序爲second, fourth, first, third
,我通過指定正確的順序矢量first, second, third, fourth
,轉型看起來是這樣的:
Before:
second fourth first third
2nd 4th 1st 3rd
2nd 4th 1st 3rd
After:
first second third fourth
1st 2nd 3rd 4th
1st 2nd 3rd 4th
雖然函數產生了所需的結果,但我的循環和STL算法的混合體感覺不穩定,通常不太可讀。在其他情況下,我通常可以使用std::sort
以及用於非標準排序的自定義比較函數,但是我無法弄清楚如何在這裏適應這種方法,其中「排序」由預定義輸入確定,而不是某種類型的基於比較的邏輯。是否有一種更習慣的方式來實現這一點 - 即更好地利用STL算法(不一定是std::sort
)或其他C++習慣用法?
這裏是一個online demo重現的情況。
我想到的第一件事:移調,排序與自定義比較,然後轉回來。 –
@ T.C。我同意:) – Barry