Тема: Сортировка списка для значений с разной длиной элементов списка

Есть список, например
(setq a1 '(2.10-1  2.10-8  2.10-100  2.10-2  2.10-10 2.10-9  2.10-99  2.10-101))
Можно ли отсортировать список по возрастанию, чтобы получился следующий порядок
(2.10-1  2.10-2  2.10-8  2.10-9  2.10-10  2.10-99  2.10-100  2.10-101)
Вся сложность в том, типовая сортировка дает другой порядок, типа
(2.10-1  2.10-10  2.10-100  2.10-2...) В этом и проблема. Нужно нестандарное решение

Re: Сортировка списка для значений с разной длиной элементов списка

Думаю, что так:

 (setq a1 '("2.10-1" "2.10-8" "2.10-100" "2.10-2" "2.10-10" "2.10-9" "2.10-99" "2.10-101"))
(VL-SORT A1
 (FUNCTION (LAMBDA (a2 a3)
  (setq i2 (read (strcat "(" (vl-string-subst " " "-" a2) ")"))
    i3 (read (strcat "(" (vl-string-subst " " "-" a3) ")")))
  (< (cadr i2) (cadr i3))))) 

Re: Сортировка списка для значений с разной длиной элементов списка

Пожалуй, так короче...

 (VL-SORT A1
 (FUNCTION
 (LAMBDA (a2 a3)
  (< (read (substr a2 (+ 2 (vl-string-search "-" a2))))
     (read (substr a3 (+ 2 (vl-string-search "-" a3)))))))) 

Re: Сортировка списка для значений с разной длиной элементов списка

Попробовал. После сортировки в списке получились восемь элементов - "двойки". Их вид изменился от исходных элементов списка. Пока не получается Задача наверное не такая простая.

Re: Сортировка списка для значений с разной длиной элементов списка

> Анатолий Б
У меня произходит только сортирофка...
Попробуй сравнить a1 и a-new

 (setq a1 '("2.10-1" "2.10-8" "2.10-100" "2.10-2" "2.10-10" "2.10-9" "2.10-99" "2.10-101"))
(setq a-new (VL-SORT A1
             (FUNCTION
               (LAMBDA (a2 a3)
             (< (read (substr a2 (+ 2 (vl-string-search "-" a2))))
                (read (substr a3 (+ 2 (vl-string-search "-" a3))))
             ) ;_  конец функции <
               ) ;_  конец функции LAMBDA
             ) ;_  конец функции FUNCTION
        ) ;_  конец функции VL-SORT
) 

Re: Сортировка списка для значений с разной длиной элементов списка

> Евгений
Да, всё обязано работать, но лучше использовать что-то такое (по мотивам представленного кода):

(mapcar (function (lambda (a) (nth a a1)))
        (vl-sort-i
          (mapcar (function
                    (lambda (b)
                      (read (substr b (+ 2 (vl-string-search "-" b))))
                    )
                  )
                  a1
          )
          (function <)
        )
)

так будет намного быстрее (при большом количестве итераций, может иметь значение).

Re: Сортировка списка для значений с разной длиной элементов списка

> ЯR
Подскажи, пожалуйста, на чем здесь экономия времени?
Очень хочется впредь писать экономнее...

Re: Сортировка списка для значений с разной длиной элементов списка

> Евгений
функция read - одна из самых медленных в AutoLISP, а в твоём коде она должна быть использована во много раз больше, чем в моём. Остальные функции строки: (read (substr a2 (+ 2 (vl-string-search "-" a2)))) - то-же из "неторопливых". Фактически, в моём примере сортировки самого списка не происходит - вычисляется индекс, а по нему работает mapcar - то-ж не быстро, но вызовов её всего два. Заметить разницу можно только на длинных списках, на коротких выигрыш будет съеден вызовами функций.

Re: Сортировка списка для значений с разной длиной элементов списка

> ЯR
СПАСИБО!

Re: Сортировка списка для значений с разной длиной элементов списка

кстати, замена read на atoi - то-же должна немного ускорить процесс, но это надо быть уверенным, что нет дробных, типа: "2.10-2.3"

Re: Сортировка списка для значений с разной длиной элементов списка

На этом тестовом наборе всё классно заработало. Спасибо!

Re: Сортировка списка для значений с разной длиной элементов списка

> ЯR
Тогда можно использовать atof

 (setq a1 '("2.10-1" "2.10-8" "2.10-100" "2.10-2"
       "2.10-10" "2.10-9" "2.10-99" "2.10-101"))
(setq a-new (VL-SORT A1
         (FUNCTION
           (LAMBDA (a2 a3)
       (< (atof (substr a2 (+ 2 (vl-string-search "-" a2))))
          (atof (substr a3 (+ 2 (vl-string-search "-" a3))))
       ) ;_  конец функции <
           ) ;_  конец функции LAMBDA
         ) ;_  конец функции FUNCTION
      ) ;_  конец функции VL-SORT
)  

Вроде тоже работает...

Re: Сортировка списка для значений с разной длиной элементов списка

А у меня вот такой смешной вариант:

(vl-sort a1
       '(lambda (x y)
               (<
             (atof (vl-string-translate "-" "e" x))
             (atof (vl-string-translate "-" "e" y))
               )
             )
       )
  )

Re: Сортировка списка для значений с разной длиной элементов списка

Смешной вариант тоже очень замечательно работает.
На самом деле эта задача  была упрощена от оригинала, так как мне казалось, что это самое трудное и неразрешимое место.
На деле эта задача чуть посложнее, так как исходный список не из одного элемента,а из пар подсписков
.
В качестве тестового списка можно поробовать на примере
(setq a1 '(("2.10-11" 2) ("2.10-8" 2) ("2.10-100" 4)  ("2.10-10" 2)  ("2.10-9" 4) ("2.10-99" 4)))
Этот список необходимо отсортировать по такаому же критерию возрастания первого параметра подсписка.
После сортировки должен получиться список
(("2.10-8" 2) ("2.10-9" 4) ("2.10-10" 2) ("2.10-11" 2) ("2.10-99" 4) ("2.10-100" 4))

Re: Сортировка списка для значений с разной длиной элементов списка

> Анатолий Б

(mapcar
  (function (lambda (a) (nth a a1)))
  (vl-sort-i
    (mapcar
      (function
        (lambda (b)
          (atoi (substr (car b) (+ 2 (vl-string-search "-" (car b)))))
        )
      )
      a1
    )
    (function <)
  )
)

Адаптировать остальные варианты - не сложнее.

Re: Сортировка списка для значений с разной длиной элементов списка

> Анатолий Б
Всегда-ли списки начинаются на
"2.10-" или бывают варианты?

Re: Сортировка списка для значений с разной длиной элементов списка

На чертеже присутствуют несколько серий например:
2.10-...    2.03-...  2.04-..
В этой задаче выбираются данные только по одной из этих групп (например 2.10-) и проводится их сортировка, затем выбирается другая группа(например 2.03-) и провдоится такая же сортировка. Выполняю это за несколько запусков прораммы.
В другой же задаче приходится сортировать эти данные совместно. Там проблема этой сортировки проскочила, так как после "тире"  шла одноразрядная цифра. Не было проблемы с появлением нового разряда числа.

Re: Сортировка списка для значений с разной длиной элементов списка

Последний вариант тест прошелуспешно. Вечерком попробую на основной программе.
Спасибо за помощь.

Re: Сортировка списка для значений с разной длиной элементов списка

Всем большое спасибо!
Всё работет как надо!!!