首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 通用資料移動演算法:支援多段、連續/不連續、上移/下移的排序重排

     編輯:關於C#

需求場景

列表資料需支援「多選、拖曳排序」,選取項目可能包含多個連續區塊(如 Key0、Key2~Key4、Key9),需一次性上移/下移並維持區塊內部相對順序。

核心資料結構

  • MoveSeqArithmeticItem<T, K>:包裝業務物件,含 Seq (排序號)、ObjKey (業務鍵)、PreviewItem/BackItem (雙向鏈表指標)、AfterSetSequenceEvent。
  • SequenceAreaEntity:連續區塊實體,含 FItem (首項)、LItem (尾項)、ArrAreas (區塊內所有項)。
  • MoveSeqArithmetic<T, K>:演算法核心,維護項目陣列與鏈表關係。

上移演算法邏輯


public void MoveUpByKeys(object[] objKeys)
{
    // 1. 依鍵值分組連續區塊 → Hashtable
    var areas = GetSequenceAreasByKeys(objKeys);

    foreach (var area in areas.Values)
    {
        // 2. 找到區塊前一個項目 (移動目標位置)
        var moveItem = GetPreviewItemByArea(area);
        if (moveItem == null) continue; // 已在最頂

        int moveIdx = moveItem.Seq;
        int firstIdx = area.FItem.Seq;
        int lastIdx = area.LItem.Seq;

        // 3. 區塊內所有項 Seq 往前平移 (壓縮空隙)
        foreach (var item in area.ArrAreas)
            item.Seq = item.Seq - firstIdx + moveIdx;

        // 4. 將區塊尾項 Seq 設為原移動目標位置 (完成置換)
        moveItem.Seq = lastIdx;

        // 5. 修復雙向鏈表指標
        area.FItem.PreviewItem = moveItem.PreviewItem;
        moveItem.PreviewItem = area.LItem;
        moveItem.BackItem = area.LItem.BackItem;
        area.LItem.BackItem = moveItem;
    }

    Sort(); // 依 Seq 重新排序陣列
}

下移演算法對稱

邏輯鏡像:尋找區塊後一個項目 (GetNextItemByArea),區塊項 Seq 往後平移,修復鏈表。

測試驗證


// 初始: Key0 Key1 Key2 Key3 Key4 Key5 Key6 Key7 Key8 Key9
// 上移 Key0, Key2~Key4, Key9
// 結果: Key0 Key2 Key3 Key4 Key1 Key5 Key6 Key7 Key8 Key9

// 下移 Key0, Key1~Key3, Key9
// 結果: Key1 Key2 Key3 Key0 Key4 Key5 Key6 Key7 Key8 Key9

設計亮點

  • 區塊抽象:SequenceAreaEntity 將離散選轉化為連續區塊集合,統一處理邏輯。
  • 雙重索引:陣列 (隨機存取) + 鏈表 (相對順序維護),Sort() 同步兩者。
  • 事件通知:AfterSetSequenceEvent 讓 UI 即時更新顯示順序。
  • 泛型設計:<T, K> 適配任意業務物件與鍵型別。

結語

將「多選拖曳排序」抽象為「連續區塊平移 + 鏈表修復」,以 Seq 為唯一排序依據,實現了高內聚、低耦合的通用移動演算法。可直接套用於 Grid、Tree、List 等各類可排序元件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved