как просуммировать данный список?
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > как просуммировать данный список?

как просуммировать данный список?

Ответ
Поиск в этой теме
Непрочитано 28.10.2011, 03:14 #1
как просуммировать данный список?
Composter
 
Отопление и вентиляция
 
Москва
Регистрация: 31.10.2008
Сообщений: 445

Добрый день.у меня получается вот такой список
(("_V_prit_01" "03_Воздуховод прямоугольный" "400x450" 2.25933)
("_V_prit_01" "03_Воздуховод прямоугольный" "400x450" 3.12518)
("_V_prit_01" "03_Воздуховод прямоугольный" "400x450" 3.60096)
("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1)
("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1)
("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1))
подскажите как мне просуммировать его что бы при совпадении первых трех элементов суммировался 4 элемент, и пустые списки удалялись.т.е. что бы в итоге получился вот такой список
(("_V_prit_01" "03_Воздуховод прямоугольный" "400x450" 8.98547)
("_V_zaslonki" "40_Дроссельное устройство" "400" 3)
("_V_zaslonki" "40_Дроссельное устройство" "500x200" 3))
Просмотров: 3576
 
Непрочитано 28.10.2011, 08:36
1 | #2
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,701
Отправить сообщение для Do$ с помощью Skype™


Код:
[Выделить все]
 (defun test (lst / rez tmp sum)
  (while lst
    (setq tmp (car lst)
	  sum (apply '+
		     (mapcar 'last
			     (vl-remove-if-not
			       '(lambda	(a)
				  (and (= (car a) (car tmp))
				       (= (cadr a) (cadr tmp))
				       (= (caddr a) (caddr tmp))
				  ) ;_ end of and
				) ;_ end of lambda
			       lst
			     ) ;_ end of vl-remove-if-not
		     ) ;_ end of mapcar
	      ) ;_ end of apply
	  rez (cons (list (car tmp) (cadr tmp) (caddr tmp) sum) rez)
	  lst (vl-remove-if
		'(lambda (a)
		   (and	(= (car a) (car tmp))
			(= (cadr a) (cadr tmp))
			(= (caddr a) (caddr tmp))
		   ) ;_ end of and
		 ) ;_ end of lambda
		lst
	      ) ;_ end of vl-remove-if
    ) ;_ end of setq
  ) ;_ end of while
  (reverse rez)
) ;_ end of defun


(test
  '(("_V_prit_01"
     "03_Воздуховод прямоугольный"
     "400x450"
     2.25933
    )
    ("_V_prit_01"
     "03_Воздуховод прямоугольный"
     "400x450"
     3.12518
    )
    ("_V_prit_01"
     "03_Воздуховод прямоугольный"
     "400x450"
     3.60096
    )
    ("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
    ("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
    ("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
    ("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1)
    ("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1)
    ("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1)
   )
) ;_ end of test
Do$ вне форума  
 
Непрочитано 28.10.2011, 09:57
1 | #3
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Мой вариант

Код:
[Выделить все]
 (defun test1 (lst / ret tmp)
  (vl-load-com)
  (foreach item
           (mapcar
             '(lambda (x)
                (setq x (reverse x))
                (list (strcase (vl-prin1-to-string (cdr x))) (car x))
              ) ;_ end of lambda
             lst
           ) ;_ end of mapcar
    (if (setq tmp (assoc (car item) ret))
      (setq ret
             (subst (list (car tmp) (+ (cadr tmp) (cadr item))) tmp ret)
      ) ;_ end of setq
      (setq ret (cons item ret))
    ) ;_ end of if
  ) ;_ end of foreach
  (mapcar '(lambda (x) (reverse (cons (cadr x) (read (car x)))))
          ret
  ) ;_ end of mapcar
) ;_ end of defun

Использование

Код:
[Выделить все]
 
(setq lst
       (list
         '("_V_prit_01" "03_Воздуховод прямоугольный" "400x450" 2.25933)
         '("_V_prit_01" "03_Воздуховод прямоугольный" "400x450" 3.12518)
         '("_V_prit_01" "03_Воздуховод прямоугольный" "400x450" 3.60096)
         '("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
         '("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
         '("_V_zaslonki" "40_Дроссельное устройство" "400" 1)
         '("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1)
         '("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1)
         '("_V_zaslonki" "40_Дроссельное устройство" "500x200" 1)
       ) ;_ end of list
) ;_ end of setq
(test1 lst)
;(
;("_V_ZASLONKI" "40_ДРОССЕЛЬНОЕ УСТРОЙСТВО" "500X200" 3)
;("_V_ZASLONKI" "40_ДРОССЕЛЬНОЕ УСТРОЙСТВО" "400" 3)
;("_V_PRIT_01" "03_ВОЗДУХОВОД ПРЯМОУГОЛЬНЫЙ" "400X450" 8.98547)
;)
Сделал регистронезависимым, если не нужно - убери strcase из функции test1
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 30.10.2011 в 18:57.
VVA вне форума  
 
Автор темы   Непрочитано 28.10.2011, 15:47
#4
Composter

Отопление и вентиляция
 
Регистрация: 31.10.2008
Москва
Сообщений: 445


спасибо большое,особенно за оперативность.лисп от vva более универсален и не зависит от того сколько элементов в каждом списке.
Composter вне форума  
 
Непрочитано 29.10.2011, 16:59
#5
CB

Конструирование в области нефтеразведки
 
Регистрация: 10.02.2006
Гомель
Сообщений: 321


Еще вариант:
Код:
[Выделить все]
 
(defun test2 (lst / temp)
  (if lst
    (progn
      (setq temp (reverse (car lst))
            lst  (vl-remove-if
                   '(lambda (a)
                      (if (equal (cdr temp) (cdr (reverse a)))
                        (setq temp
                               (cons (+ (last a) (car temp))
                                     (cdr temp)
                               ) ;_ end of cons
                        ) ;_ end of setq
                      ) ;_ end of if
                    ) ;_ end of lambda
                   (cdr lst)
                 ) ;_ end of vl-remove-if
      ) ;_ end of setq
      (cons (reverse temp) (test2 lst))
    ) ;_ end of progn
  ) ;_ end of if
) ;_ end of defun

;;;Вызов  (test2 lst)
__________________
Никогда не спорьте с дураками - они опустят Вас до своего уровня и победят за счет опыта
CB вне форума  
 
Непрочитано 29.10.2011, 17:40
#6
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Если воспользоваться рекурсией:

Код:
[Выделить все]
 (defun test (l)
  (if l
    (if (equal (cdr (reverse (car l))) (cdr (reverse (cadr l))))
      (test (cons (reverse (cons (+ (last (car l)) (last (cadr l))) (cdr (reverse (car l))))) (cddr l)))
      (cons (car l) (test (cdr l)))
    )
  )
)
Программа только для отсортированного списка.
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 29.10.2011, 18:46
#7
Oliver_88

"ценный кадр"
 
Регистрация: 02.12.2010
Сообщений: 115
<phrase 1=


Самый длинный вариант.
Код:
[Выделить все]
 (defun test2  (lst)
  (if lst
    (cons
      (reverse
	(cons
	  (apply '+
		 (mapcar
		   'last
		   (vl-remove-if-not
		     '(lambda (x)
			(equal
			  (cdr (reverse x))
			  (cdr (reverse (car lst)))
			  )
			)
		     lst
		     )
		   )
		 )
	    (cdr
	      (reverse (car lst))
	      )
	  )
	)
      (test2
	(vl-remove-if
	  '(lambda (x)
	     (equal
	       (cdr (reverse x))
	       (cdr (reverse (car lst)))
	       )
	     )
	  lst
	  )
	)
      )
    )
  )
Oliver_88 вне форума  
 
Непрочитано 29.10.2011, 22:44
#8
Li6-D


 
Регистрация: 03.05.2009
Сообщений: 112


Незатейливо:
Код:
[Выделить все]
 (defun test3 (lst / s p lst1)
  (while lst
    (setq s 0 
          p (cdr (reverse (car lst)))
          lst (vl-remove-if
               '(lambda (x) (if (equal p (cdr (reverse x))) (setq s (+ s (last x)))))
                lst
              )
          lst1 (cons (reverse (cons s p)) lst1)
  ) )
  (reverse lst1)
)
Li6-D вне форума  
 
Непрочитано 31.10.2011, 12:02
#9
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,701
Отправить сообщение для Do$ с помощью Skype™


Offtop: Конкурс, однако
Do$ вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > как просуммировать данный список?

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
SCAD Office 11.1 Новые возможности EUDGEN SCAD 632 20.02.2013 17:13
Как передать функции (getkword) Список ключевых слов из списка? Kostinok Программирование 31 31.05.2012 13:08
Помогите новичку! Параметаризация детали на AutoLISPe!!! Nica_019 LISP 21 04.02.2011 19:56
Lisp. Вставка в список. back1981 LISP 12 27.12.2010 20:48
Помощь по Лире Серега М Лира / Лира-САПР 52 28.05.2007 02:47