【IDL】实现双重排序功能(更新降序)

功能介绍

输入数据为2*N的二维数组,即2列N行。首先根据某一列进行排序,然后对于此列中值相同的位置,根据另一列值进行排列。

调用方法

arrNew = double_sort(arr,idx,type)

其中,arr为输入数组,保证为2*N大小。

idx:  0 – 首先按第一列排序(默认);

      1 – 首先按第二列排序。

type: 0 - 均按升序排序(默认);

      1 – 均按降序排序;

      2 – 首先按升序,然后按降序;

      3 – 首先按降序,然后按升序。

函数代码

;+
; :Description:
;   Double Sort
;
; :Input:
;   input array dimensions: 2*N
;   idx: 0 - Sort by the first column firstly (Default)
;        1 - Sort by the second column firstly
;   type: 0 - ascending sort both columns (Default)
;         1 - descending sort both columns
;         2 - ascending sort firstly, and the descending sort
;         3 - descending sort firstly, and then ascending sort
;
; :Output:
;   output sorted array: 2*N;
;
; :Example:
;   arr = [[9,4],[3,4],[3,1],[2,6],[9,6],[3,5],[5,4]]
;   arrNew = double_sort(arr, 1, 3)
;
; :Author: duhj@esrichina.com.cn
;-
 
FUNCTION DOUBLE_SORT, arr, idx, type
 
  COMPILE_OPT idl2
  print , n_elements(arr)
  ;
  ;判断输入数组是否为2*N
  IF ~N_ELEMENTS(arr) THEN BEGIN
   MESSAGE, 'Incorrect number of arguments', /continue
   RETURN, !null
  ENDIF ELSE BEGIN
   IF (SIZE(arr, /DIMENSIONS))[0] NE 2 $
    OR SIZE(arr, /N_DIMENSIONS) NE 2 THEN BEGIN
     MESSAGE, 'Please input array with 2*N dimensions', /continue
     RETURN, !null
   ENDIF
  ENDELSE
 
  ;判断按第几列排序,默认为0
  ;  0 --- 按第一列先排序
  ;  1 --- 按第二列先排序
  IF ~N_ELEMENTS(idx) THEN BEGIN
   idx = 0
  ENDIF ELSE BEGIN
   IF idx NE 0 AND idx NE 1 THEN BEGIN
     MESSAGE, 'Input index must be one of the value:0,1', /continue
     RETURN, !null
   ENDIF
  ENDELSE
 
  ;判断排序类型,降序or升序
  ;  0 - 均按升序排序
  ;  1 - 均按降序排序
  ;  2 - 首先按升序,然后按降序
  ;  3 - 首先按降序,然后按升序
  IF ~N_ELEMENTS(type) THEN BEGIN
   type = 0
  ENDIF
 
  arr1 = arr[1-idx,*]
  arr2 = arr[idx,*]
 
  CASE type OF
   0: BEGIN
     arr1sort = arr1[SORT(arr2)]
     arr2sort = arr2[SORT(arr2)]
     
     R = HISTOGRAM(arr2sort, location = loc)
     
     eValue = loc[WHERE(HISTOGRAM(arr2sort) GT 1)]
     
     FOREACH element, eValue DO BEGIN
       eIdx = WHERE(arr2sort EQ element)
       arr1sort[eIdx] = (arr1sort[eIdx])[SORT(arr1sort[eIdx])]
     ENDFOREACH
   END
   1: BEGIN
     arr1sort = REVERSE(arr1[SORT(arr2)])
     arr2sort = REVERSE(arr2[SORT(arr2)])
     
     R = HISTOGRAM(arr2sort, location = loc)
     
     eValue = loc[WHERE(HISTOGRAM(arr2sort) GT 1)]
     
     FOREACH element, eValue DO BEGIN
       eIdx = WHERE(arr2[REVERSE(SORT(arr2))] EQ element)
       arr1sort[eIdx] = (arr1sort[eIdx])[(REVERSE(SORT(arr1sort[eIdx])))]
     ENDFOREACH
   END
   2: BEGIN
     arr1sort = (arr1[SORT(arr2)])
     arr2sort = (arr2[SORT(arr2)])
     
     R = HISTOGRAM(arr2sort, location = loc)
     
     eValue = loc[WHERE(HISTOGRAM(arr2sort) GT 1)]
     
     FOREACH element, eValue DO BEGIN
       eIdx = REVERSE(WHERE(arr2sort EQ element))
       arr1sort[eIdx] = ((arr1sort[eIdx])[((SORT(arr1sort[eIdx])))])
     ENDFOREACH
   END
   3: BEGIN
     arr1sort = REVERSE(arr1[SORT(arr2)])
     arr2sort = REVERSE(arr2[SORT(arr2)])
     
     R = HISTOGRAM(arr2sort, location = loc)
     
     eValue = loc[WHERE(HISTOGRAM(arr2sort) GT 1)]
     
     FOREACH element, eValue DO BEGIN
       eIdx = (WHERE(arr2sort EQ element))
       arr1sort[eIdx] = ((arr1sort[eIdx])[((SORT(arr1sort[eIdx])))])
     ENDFOREACH
   END
   ELSE: BEGIN
     MESSAGE, 'Please input the correct argument of type.', /continue
     RETURN, !null
   END
  ENDCASE 
 
  arrNew = arr
 arrNew[1-idx,*] = arr1sort
  arrNew[idx,*] = arr2sort
 
  RETURN, arrNew
END

调用示例

IDL> arr = [[9,4],[3,4],[3,1],[2,6],[9,6],[3,5],[5,4]]
IDL> print, arr
      9      4
      3      4
      3      1
      2      6
      9      6
      3      5
      5      4
IDL> ;均按默认,则首先按第一列排序,均为升序。
IDL> print, double_sort(arr)
      2      6
      3      1
      3      4
      3      5
      5      4
      9      4
      9      6
IDL> ;首先按第二列排序,先升后降。
IDL> print, double_sort(arr,1,2)
      3      1
      9      4
      5      4
      3      4
      3      5
      9      6
      2      6

 

posted @   ENVI-IDL技术殿堂  阅读(272)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示