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

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

Как изменить одно значение сложного списка ?

Ответ
Поиск в этой теме
Непрочитано 05.06.2010, 15:32 #1
Как изменить одно значение сложного списка ?
swkx
 
Регистрация: 22.01.2010
Сообщений: 311

День добрый.

lst - список вида ((1 a1 b1 c1) (2 a2 b2 c2) (3 a3 b3 c3) ....)

Подскажите, как мне какому-нибудь элементу списка присвоить определённое значение, например b2 = "X" и c2 = 100, т.е. обновленный список должен быть ((1 a1 b1 c1) (2 a2 "Х" 100) (3 a3 b3 c3) ....)
Просмотров: 6354
 
Непрочитано 05.06.2010, 16:51
#2
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


если в вашем представлении списка - то обычным mapcar'ом, если списки "сложновложенные" то рекурсией. На вскидку:
Код:
[Выделить все]
(defun subst-rec (x y lst);заменяет все x на y (потенциально проблемы с точностью при дробных числах - но суть такая)
   (if	(listp lst)
	(mapcar '(lambda (lst) (subst-rec x y lst)) lst)
	(if (= x lst) y lst)))
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 05.06.2010, 17:25
#3
swkx


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


Ёлы-палы, для такой примитивной операции в лиспе не предусмотрено никаких функций ?
Получается, получить значения из моего списка можно просто:
(nth num1 (nth num2 lst)), а вернуть обновлённые значения обратно в список можно только с помощью вспомогательных функций ?
Не проще тогда совсем удалить элемент (2 a2 b2 c2) из списка, сформировать его заново с другими значениями b2 и c2 и добавить (2 a2 "X" 100) в исходный список ?
swkx вне форума  
 
Непрочитано 05.06.2010, 17:28
#4
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,404


А чем обычный subst не катит? Да, код будет сложным - ну так и список не простой...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 05.06.2010, 17:55
#5
swkx


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


Алексей, SUBST я проглядел. Пробую сообразить, как его применить. Порядок действий:
1. Запоминаю элемент списка (2 a2 b2 c2)
2. Меняю с помощью SUBST элементы подсписка b2 c2.
3. Меняю опять же с помощью SUBST (2 a2 b2 c2) на (2 a2 "Х" 100) в списке lst.
Ты это имел в виду ?
swkx вне форума  
 
Непрочитано 06.06.2010, 11:16
#6
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от swkx Посмотреть сообщение
Ёлы-палы, для такой примитивной операции в лиспе не предусмотрено никаких функций ?
Все послесказанное сугубо ИХМО - я узнаю Ваше недоумение функционалом лиспа - оно класично для недавно перехедших (заглянувших) с классических (императивных) алгоритмических языков (в том числе и меня), если Вы продолжите заниматься лиспом - я уверен на все 100 у Вас отпадет надобность в 99% "лиспонепредусмотренных" операций - просто начнете мыслить по лисповски "мапкарно-рекурсивно".
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 06.06.2010, 11:56
#7
swkx


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


Дима_,
программирование на лиспе - нечто вроде хобби для меня, занимаюсь им не очень часто, но с большим удовольствием. Недоумение некоторые лисповские цацки действительно вызывают, но недоумение ни в коем случае не означает недовольство этим языком.
А в данном конкретном случае мне вполне хватило двойного применения SUBST.
И мыслить по-лисповски не начну - старый уже для этого
swkx вне форума  
 
Непрочитано 06.06.2010, 12:00
#8
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Дима_ Посмотреть сообщение
я уверен на все 100 у Вас отпадет надобность в 99% "лиспонепредусмотренных" операций
И какой простор для творчества в узкоспециализированныйх задачах...
gomer вне форума  
 
Непрочитано 06.06.2010, 12:02
#9
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,404


Код:
[Выделить все]
(defun test (/ a1 b1 c1 a2 b2 c2 a3 b3 c3 b1_r c2_r res)
  (setq a1   1.1
        b1   1.2
        c1   1.3
        a2   2.1
        b2   2.2
        c2   2.3
        a3   3.1
        b3   3.2
        c3   3.3
        lst  (list (list 1 a1 b1 c1) (list 2 a2 b2 c2) (list 3 a3 b3 c3))
        b1_r "x"
        c2_r 100
        ) ;_ end of setq
  (setq res (subst (list 2 a2 b2 c2_r)
                   (assoc 2 (setq lst (subst (list 1 a1 b1_r c1) (assoc 1 lst) lst)))
                   lst
                   ) ;_ end of subst
        ) ;_ end of setq
  ) ;_ end of defun
Код:
[Выделить все]
_$ (test)
((1 1.1 "x" 1.3) (2 2.1 2.2 100) (3 3.1 3.2 3.3))
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 06.06.2010, 12:11
#10
swkx


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


gomer,
прав абсолютно, возиться всё время с классическими базами данных не то чтобы надоедает, а как-то приедается
Кулик,
спасибо, подтвердил правильность моих мыслей, я примерно так и сделал, но не так красиво
swkx вне форума  
 
Непрочитано 06.06.2010, 17:31
#11
Do$

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


Как вариант :
Код:
[Выделить все]
(defun set-value-in-list-with-index (lst ind1 ind2 new_val / i1 i2)
				    ;|
lst - сложный список
ind1 - номер списка в сложном списке (целое число, нумерация начинается с 1)
ind2 - номер элемента в списке (целое число, нумерация начинается с 1)
new_val - новое значение

Пример вызова:
(set-value-in-list-with-index '((11 12 13) (21 22 23) (31 32 33)) 2 3 "test")
->((11 12 13) (21 22 "test") (31 32 33))
|;
  (setq	i1 0
	i2 0
  ) ;_ end of setq
  (mapcar '(lambda (ins_lst)
	     (if (= (setq i1 (1+ i1)) ind1)
	       (mapcar '(lambda	(x)
			  (if (= (setq i2 (1+ i2))
				 ind2
			      ) ;_ end of =
			    new_val
			    x
			  ) ;_ end of if
			) ;_ end of lambda
		       ins_lst
	       ) ;_ end of mapcar
	       ins_lst
	     ) ;_ end of if
	   ) ;_ end of lambda
	  lst
  ) ;_ end of mapcar
) ;_ end of defun
Do$ вне форума  
 
Автор темы   Непрочитано 06.06.2010, 18:47
#12
swkx


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


Do$,
если скажу, что что-нибудь понял, то совру

И потом, первоначальный вариант с двумя SUBST меня удовлетворил полностью. В основном тем, что я представляю, как ОНО работает
swkx вне форума  
 
Непрочитано 07.06.2010, 08:55
#13
Do$

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


Да я и не настаиваю на применении моего варианта Написал для примера и для собственной разминки. Единственное, хочу предостеречь:
Цитата:
Сообщение от swkx Посмотреть сообщение
первоначальный вариант с двумя SUBST меня удовлетворил полностью
То есть сперва subst применяется ко вложенному списку, заменяя число? Если так, то это может привести к ошибке. Может оказаться, что в списке два одинаковых числа и заменится не только то, которое нужно. К примеру: (subst "test" 23.4 '(1 23.4 34.6 23.4)).
Do$ вне форума  
 
Автор темы   Непрочитано 07.06.2010, 09:48
#14
swkx


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


Цитата:
Сообщение от Do$ Посмотреть сообщение
Может оказаться, что в списке два одинаковых числа и заменится не только то, которое нужно.
Я на это уже нарвался, пришлось изменить структуру так, что во вложенном списке все четыре элемента разных типов. В моём случае это возможно.
swkx вне форума  
 
Непрочитано 07.06.2010, 16:37
1 | #15
VVA

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


Набор функций для работы с i-ми элементами списка
Код:
[Выделить все]
 (defun remove-i (i lst)
;;;Ф-ция удаляет i-й(начиная с 0) элемент списка
;;; i - индекс элемента
;;;lst- список

      (setq i (1+ i))
      (vl-remove-if '(lambda (x) (zerop (setq i (1- i)))) lst)
    ) ;_ end of defun
(defun Insert-i (pos item lst / tmp)
;;;Ф-ция вставляет в позицию pos (начиная с 0) элемент списка item
;;; pos - индекс (позиция) начиная с 0
;;;; item - элемент списка
;;;  lst- список
;_http://www.theswamp.org/index.php?topic=14226.0
       (if (< -1 pos (1+ (length lst)))
        (progn
          (repeat pos
            (setq tmp (cons (car lst) tmp)
                  lst (cdr lst)
            )
          )
          (append (reverse tmp) (list item) lst)
        )
        lst
      )
    )
(defun subst-i (i itm lst)
;;;================================================================================
;;;Ф-ция изменяет i-й(начиная с 0) элемент списка новым значением
;;; i - индекс элемента
;;;itm - новое значение
;;;lst - список
;;;http://www.theswamp.org/index.php?topic=14170.0
      
      (setq i (1+ i))
      (mapcar
        '(lambda (x)
           (if (zerop (setq i (1- i)))
             itm
             x
           ) ;_ end of if
         ) ;_ end of lambda
        lst
      ) ;_ end of mapcar
    ) ;_ end of defun
;;;;;=======================================
Пример замены во всех подсписках 2-го и 3-го (начиная с 0) элемента
Код:
[Выделить все]
(setq a1   1.1
        b1   1.1
        c1   1.1
        a2   1.1
        b2   1.1
        c2   1.1
        a3   1.1
        b3   1.1
        c3   1.1
        lst  (list (list 1 a1 b1 c1) (list 2 a2 b2 c2) (list 3 a3 b3 c3))
        b1_r "x"
        c2_r 100
        ) ;_ end of setq
(mapcar '(lambda(x)(subst-i 2 "Это 2" (subst-i 3 "Это 3" x))) lst)
;;;-> ((1 1.1 "Это 2" "Это 3") (2 1.1 "Это 2" "Это 3") (3 1.1 "Это 2" "Это 3"))
Осталось добавить условие для замены
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 07.06.2010, 23:06
#16
swkx


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


Уважаемые коллеги, как-то всё сложно у вас
Я делаю по-другому.

Код:
[Выделить все]
(setq OldElem (car (vl-member-if (function
(lambda (e) (= (caar e) num))
)
lst)
)
NewElem (subst NewValue1 (cadr OldElem) OldElem)
NewElem (subst NewValue2 (caddr OldElem) NewElem)
lst (subst NewElem OldElem lst)
); end of setq
num - по этому 1-му элементу подсписка отыскиваю сам подсписок в списке
NewValue1 - меняю 2-й эл. подсписка
NewValue2 - меняю 4-й эл. подсписка
swkx вне форума  
 
Непрочитано 07.06.2010, 23:53
#17
CB

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


Код:
[Выделить все]
(setq lst '((1 a1 b1 c1) (2 a2 b2 c2) (3 a3 b3 c3)))
(setq n '((b2 "X") (c2 100) (c3 200)))
(mapcar
  '(lambda (x)
     (mapcar
       '(lambda (y / item)
          (if (setq item (assoc y n))
            (cadr item)
            y
          ) ;_ end of if
        ) ;_ end of lambda
       x
     ) ;_ end of mapcar
   ) ;_ end of lambda
  lst
) ;_ end of mapcar
 
->((1 A1 B1 C1) (2 A2 "X" 100) (3 A3 B3 200))
CB вне форума  
 
Непрочитано 08.06.2010, 01:53
#18
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от swkx Посмотреть сообщение
Уважаемые коллеги, как-то всё сложно у вас
Я делаю по-другому.

Код:
[Выделить все]
(setq OldElem (car (vl-member-if (function
(lambda (e) (= (caar e) num))
)
lst)
)
NewElem (subst NewValue1 (cadr OldElem) OldElem)
NewElem (subst NewValue2 (caddr OldElem) NewElem)
lst (subst NewElem OldElem lst)
); end of setq
num - по этому 1-му элементу подсписка отыскиваю сам подсписок в списке
NewValue1 - меняю 2-й эл. подсписка
NewValue2 - меняю 4-й эл. подсписка
Угу. Я видимо пропустил, что задано условие уникальности всех элементов списка. Или я не прав? :-)
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 08.06.2010, 07:38
#19
swkx


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


Прав, условие уникальности не упоминалось. Кроме того, сама структура списка списка немного изменилась:
(((num1) a1 b1 c1) ((num2) a2 b2 c2)...)
num пришлось загнать в собственный подсписок, чтобы при случайном равенстве с b функция SUBST его не зацепила.
a - строковый тип
b - вещ. число
c - логический тип
swkx вне форума  
 
Непрочитано 08.06.2010, 08:22
#20
CB

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


Цитата:
num - по этому 1-му элементу подсписка отыскиваю сам подсписок в списке
NewValue1 - меняю 2-й эл. подсписка
NewValue2 - меняю 4-й эл. подсписка
Где и как ты задаешь в программе номер подсписка, какие элементы в нем нужно заменить и на что нужно заменить?
CB вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как изменить одно значение сложного списка ?



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Рифмоплетство. Kryaker Разное 554 14.11.2023 11:59
Как изменить единицу измерения расхода воздуха в Aunocad MEP 2009? samchik Вертикальные решения на базе AutoCAD 8 06.05.2009 17:18
как изменить окраску изометрии sdndrey AutoCAD 1 01.06.2004 08:55
как изменить окраску 3D модели sdndrey AutoCAD 3 31.05.2004 23:55
как изменить радиус окружности sasa AutoCAD 11 02.12.2003 02:23