網格中合併 Merge 功能的多種技術方案

2021-04-13 14:26:55 字數 1488 閱讀 3516

2023年12月26日 23:46:00

寫這篇文章,主要是因為我們的"下午茶時間"(專案內部的一種交流方式)激烈地討論了此類功能的多種實現,我感覺非常有意思。大家可以參考一下。

我先簡單地描述一下功能要求,要求設計一種資料結構,支援網格控制項(圖形化)實現矩形區域的合併效果(merged)。非矩形區域的合併不在支援範圍之內。

大家可能都在使用各種各樣的網格控制項,最出名的可能是flexgrid。不過大家可以也思考思考,如果是你的話,你會如何設計呢?

有乙個最基本的方法,每乙個網格cell中預置乙個變數:mergeid。我們姑且將這種方法稱之為"mergeid法"。此方法規則比較簡單:沒有合併的cell的mergeid都是0,相鄰矩形區域的合併cells的mergeid相同,且不為0。將0特殊處理,是為了加快處理速度,畢竟,大多數都是沒有合併的cell。

11

1001

1100

0001

1000

11

如上面的網格,則左上角六個cell合併,右下角四個cell合併。

這種方法的最大問題在於,空間占有比較浪費,特別是對那些從沒有合併的cell。另外,對於合併格的描述不清晰,整個網格中有多少合併格也不能簡單獲取,必須經過遍歷才知道。

針對上面的分析,提出第二種方案,我們稱之為"mergerange list",這種方法的最大優勢在於將所有合併的矩形區域統一管理起來,形成乙個列表。網格控制項在訪問merge屬性的時候,再到range列表中查詢,如果找到,則屬於合併格,否則為非合併格。

這個方式在flexgrid就被使用。顯然這種方法比較成熟。不過這種方式在管理物件的時候,不容易對應。需要經過對映。這在需要大量訪問網格cell物件的時候,會產生一些效率浪費。

熟悉html的人,大概還知道html的表示方式,在網格上通過rowspan和colspan來定義。在有合併的cell的左上角上,定義其向右和向下的合併範圍。通過這個範圍定義,我們也可以確定合併區域。這種方式的定義簡單。不過實現起來,其實有一些問題。

我們上面討論幾種方案的時候,忽略了乙個問題,那就是我們一般的網格結構,很可能是乙個cell對應乙個物件。那樣的話,我們可以有乙個新的方案,這個方案和第乙個mergeid方案聯絡在一起,但是我們不需要額外的mergeid屬性,而是直接使用object的物件指標。只需要判斷cell周圍的物件是否相等,就可以知道其合併範圍。合併區域的所有cell的物件相同。這樣,在取資料的時候,不需要進行額外對映。而在網格控制項繪製的時候,才需要合併區域查詢。效率應該可以滿足。我們就將這種方法叫"ojbect/mergeid"吧。

總結列舉一下四種方法:

mergeid

mergerange list

span

object/mergeid

這四種方法各有利弊。其實在我們設計過程中,應該抓住乙個基本點,要的是空間還是效率,還是兩者都要。不同的要求,使用不同的設計。

SVN合併 merge 的使用

原文 分支用來維護獨立的開發支線,在一些階段,你可能需要將分支上的修改合併到最新版本,或者將最新版本的修改合併到分支。此操作十分重要,在團隊開發中,如果你是svn 的維護者此環節可以說是必不可少,因為團隊開發中如果使用了分支,那樣合併分支到主幹 或者分支合併分支的操作是必須的。如果不使用分支,直接在...

opencv中的merge函式

該函式用來合併通道 原型版本一 void merge const mat mv,size t count,outputarray dst 第乙個引數是影象矩陣陣列,第二個引數是需要合併矩陣的個數,第三個引數是輸出 版本二void merge const vector mv,outputarray d...

oracle中merge的神奇

merge into tb1 a using select b.id,c.price from tb2 b left join tb3 c where b.id c.id d 這裡using 可以子查詢 on a.id d.id when matched then udpdate a.price b...