FastFiber

item of element vervangen in een lijst/matrix OPGELOST

Gestart door delangstevandestraat, ma 15 05 2017, 11:26:11

Vorige topic - Volgende topic

delangstevandestraat

Ik was op zoek naar een stukje code om een item te vervangen in een lijst.

(achterliggend probleem eventjes schetsen, zodat jullie mee zijn ;-) )
Ik heb een selset met blocks er in. deze blocks bevatten een volgnummer in hun naam.
Met elk van die blocks wil ik iets doen.
Eens ik de actie gedaan heb wil ik dit onthouden in een lijst, bvb op de N-de positie waarbij N het volgnummer is uit de blocknaam.
Sommige blocks hebben een volgnummer dat reeds behandeld is geweest, vandaar de lijst met 'vlagjes' waardoor mijn code elk volgnummer dus maar een keer behandeld.

Ik hoop dat iedereen snapt waar ik naar toe wil...

Misschien kennen jullie al code die dit doet, geen probleem ik het een perfect stukje code gevonden die dit doet
;; Lee Mac
;;  will substitute a supplied item with item on nth position in list. ;;
;;  Arguments:                                                         ;;
;;  a - item to substitute                                             ;;
;;  n - position in list to make the substitution                      ;;
;;  l - list in which to make the substitution                         ;;
(defun LM:SubstNth (a n l)
  (if l ;if list
    (if (zerop n) ;if n = 0 ?
      (cons a (cdr l)) ;then voeg a vooraan toe aan lijst
      (cons (car l) (LM:SubstNth a (1- n) (cdr l))) ;else haal eerste ent uit lijst en doe code opnieuw met rest v/d lijst
    )
  )
)


Geen probleem dus, maar nu wil een stapje verder, en zoek ik dus code om een item te wijzigen in een lijst van lijsten, (een matrix dus eigenlijk)

ik dacht
(defun wv:substnthmth (a row col l)
  (if l
    (if (zerop row)
      (progn
(setq sl (car l))
        (setq sl (LM:substnth a col sl))
(setq l (cons sl (cdr l)))
      )
      (cons (car l) (wv:substnthmth a (1- row) col (cdr l)))
    )
  ) 
)


Maar dit doet niet wat ik dacht dat het zou doen,

om te debuggen had ik een lijstje gemaakt en dan de codeoproep
(setq lijstje (list (list 1 2 3 4) (list 5 6 7 8) (list 9 10 11 12) (list 13 14 15 16)))
(wv:substnthmth 0 1 2 lijstje)


dan zou op rij 2 het 3e element 0 worden en de lijst er dan zo moeten uitzien

( (1 2 3 4) (5 6 0 8 ) (9 10 11 12) (13 14 15 16)))

bij het stap per stap debuggen zie ik wel wanneer het fout loopt maar ik weet niet waarom en hoe ik het juist krijg...

wie kan helpen ?
Ik hou van werken,
ik kan er uuuren naar kijken...
daarom zorg ik ook dat er altijd genoeg overblijft voor morgen :-)

roy_043

#1
Hier werkt de code zoals jij in gedachten hebt.
Maar waarom werk je niet met een 'platte' lijst met namen?:
(if (not (vl-position (strcase blkNme) doneLst))
  (progn
    ... ; Actie.
    (setq doneLst (cons (strcase blkNme) doneLst))
  )
)

delangstevandestraat

hoezo het werkt ?

als je erdoor stap met een watch op lijstje, sl en l bvb

dan wordt eerst de wv lus aangesproken,
  deze roept een tweede wv-lus op
    deze roept een LM lus op, in deze lus wordt de 0 vervangen en dat zie ik ook in de watch sl
  dan wordt de teruggekeerd naar de tweed wv-lus en ik zie bij l de juiste oplossing staan, maar bij het verder verwerken hiervan 'floept' die 0 plots weer weg.

ook nadat de eerst gestartte lus ten einde is, verwacht ik in lijstje die 0 op plaats 7 en die is er niet...

wat bedoel je met een platte lijst ? slechts 1 lijst, dit is niet mogelijk wegens de opbouw en grootte van het geheel,
in uw verkenner op uw pc gooi je toch ook niet alles in één map ;-)
Ik hou van werken,
ik kan er uuuren naar kijken...
daarom zorg ik ook dat er altijd genoeg overblijft voor morgen :-)

roy_043

Controleer of je in de rest van jouw code ergens een setq bent vergeten. De lijst wordt niet 'in-place' gewijzigd.

(defun LM:SubstNth (a n l)
  (if l
    (if (zerop n)
      (cons a (cdr l))
      (cons (car l) (LM:SubstNth a (1- n) (cdr l)))
    )
  )
)

(defun wv:substnthmth (a row col l)
  (if l
    (if (zerop row)
      (cons (LM:substnth a col (car l)) (cdr l))
      (cons (car l) (wv:substnthmth a (1- row) col (cdr l)))
    )
  ) 
)


: (setq lijstje (list (list 1 2 3 4) (list 5 6 7 8) (list 9 10 11 12) (list 13 14 15 16)))
((1 2 3 4) (5 6 7 8) (9 10 11 12) (13 14 15 16))
: (wv:substnthmth 0 1 2 lijstje)
((1 2 3 4) (5 6 0 8) (9 10 11 12) (13 14 15 16))

delangstevandestraat

aha,
nu snap ik het denk ik,
ik dacht dat ik het zou zien, door te watchen naar lijstje,
maar je ziet het blijkbaar niet tijdens debug,

heb dan code aangepast
(setq lijstje (wv:substnthmtnh 0 1 2 lijstje))

dan zag ik het wel...

stom van mij.. weeral
vragen waarom het niet werkt, terwijl het wél werkt...  :oops: :oops: :cry: :cry:
Ik hou van werken,
ik kan er uuuren naar kijken...
daarom zorg ik ook dat er altijd genoeg overblijft voor morgen :-)