LISP2LEARN Posted June 9, 2011 Posted June 9, 2011 Need your help again guys. I need to search for 2 strings on a variable. If the 2 strings are found, the program will return True. Code will be like this: If "jose" is not found --returns false and don't need to look for the 2nd string If "jose" is found then search for the next string Second string can be either one on the list '("Michael" "Domino" "Carlos" "Smith" etc.) if not on the list, return false. I accomplish my goal by using (2) if (vl-string-search) functions and then copy the code and paste it 4 times then search for the second strings by changing the 2nd string that I need to search. Pretty funny and long routine but it works. Now I need to lend me your mind on how can I do this by using a list. Thanks. (defun c:test () (vl-load-com) (setq myname "Jose Chan Smith") (setq mylist ("Michael" "Domino" "Carlos" "Smith")) (if (vl-string-search "JOSE" (strcase myname)) ;;;<-- need your help here ;;;<-- I'm stuck (princ "Strings found") (princ "Strings not found") ) (PRINC) ) Quote
BIGAL Posted June 9, 2011 Posted June 9, 2011 (setq myname '("Jose" "Chan" "Smith")) (nth 1 myname) = "Chan" also for clarity sometimes (setq myname '( "Jose" "Chan" "Smith" )) Quote
Lee Mac Posted June 9, 2011 Posted June 9, 2011 (defun test ( str ) (and (vl-string-search "JOSE" (setq str (strcase str))) (vl-some '(lambda ( x ) (vl-string-search x str)) '("MICHAEL" "DOMINO" "CARLOS" "SMITH")) ) ) Quote
irneb Posted June 9, 2011 Posted June 9, 2011 You could use the member function to check if a name is in the list (or use the vl-position to get its index), but then remember that the search is case sensitive so "MICHEAL" will not match ("Micheal" ...). As for the vl-string-search, you've already got that portion working. Now to allow case-insensitivity you need to have the list in upper/lower case. Here's a "quick" way of changing this list: (setq mylist (mapcar 'strcase mylist)) Then using member or vl-position: (if (member "DOMINO" mylist) ;Could also be (vl-position "DOMINO" mylist) (princ "Domino found.") (princ "Domino not found.") ) BTW, member returns a list starting at the found item onwards - thus above it would actually return ("DOMINO" "CARLOS" SMITH"). So in general it's less efficient than vl-position (which only returns an integer of the position it was found in - above it would return 1). Both return nil if not found. Quote
LISP2LEARN Posted June 9, 2011 Author Posted June 9, 2011 Thanks guys. I'm almost there. Sorry for my poor english and explanation. Since I doing a list I might as well add Jose on the list. My bad didn't think about that before. Here is the thing.. I need the 2 strings to be on the list. First string to find is Jose. If Jose is NOT on the list, exit cleanly. No need to search for the second string If Jose is found, Look for the 2nd string on the list. If the second string is found also. Both string were found so "run my code" What troubles me is Jose is always given and the second String is not. So I have to guess what the other string is base on the list. Sorry for the trouble , this is just a problem/solving that struck me when I was reading the "IF, AND , OR, COND" functions. Lee and irneb help me in solving the second string search to make it simple. That will do it so I dont have to paste my cose 4 times, but I need for the a better solution. Perhaps a better explanation is my long code (if (vl-string-search "Jose" (strcase Mylist)) (progn (if (vl-string-search "[b]Michael[/b]" (strcase Mylist)) (progn ) ) (princ "[b]Michael[/b] not Found. Do nothing ) ) (princ "Jose not Found. Do nothing") ) (if (vl-string-search "Jose" (strcase Mylist)) (progn (if (vl-string-search "[b]Domino[/b]" (strcase Mylist)) (progn ) ) (princ "[b]Domino[/b] not Found. Do nothing ) ) (princ "Jose not Found. Do nothing") ) (if (vl-string-search "Jose" (strcase Mylist)) (progn (if (vl-string-search "Carlos" (strcase Mylist)) (progn ) ) (princ "Carlos not Found. Do nothing ) ) (princ "Jose not Found. Do nothing") ) (if (vl-string-search "Jose" (strcase Mylist)) (progn (if (vl-string-search "Smith" (strcase Mylist)) (princ "[b]Both Jose and Smith were Found.[/b] ) ) (princ) ) (princ "Jose not Found. Do nothing") ) Quote
irneb Posted June 9, 2011 Posted June 9, 2011 You cannot use vl-string-search directly on the myList variable. The reason being it contains a list and not a string. So you need to do something similar to Lee or my codes. Anyhow, here's mine: (defun c:TestStrings (/ myName myList Name1 Name2 p1 p2) (setq myName "Jose Chan Smith" myList '("Michael" "Domino" "Carlos" "Smith")) (if (and (setq Name1 (getstring "\nEnter 1st name: ")) (setq Name2 (getstring "\nEnter 2nd name: "))) (if (setq p1 (vl-string-search (strcase Name1) (strcase myName))) (progn (princ (strcat "\n" Name1 " found at position " (itoa p1) " in myName string. ")) (if (setq p2 (vl-position (strcase Name2) (mapcar 'strcase myList))) (princ (strcat Name2 " found at position " (itoa p2) " in myList. ")) (princ (strcat Name2 " not found in myList. ")) ) ) (princ (strcat "\n" Name1 " not found in myName string.")) ) (princ "\nCanceled.") ) (princ) ) Edit: Just a query to Lee. Why are you using the vl-some and then the vl-string-search? You could either have done the vl-some with a simple eq instead, or I think the vl-position (as I've got it) would be more efficient in this case. Not sure though. Quote
irneb Posted June 9, 2011 Posted June 9, 2011 And if you don't want it to even ask for the 2nd name if the 1st is not found: (defun c:TestStrings (/ myName myList Name1 Name2 p1 p2) (setq myName "Jose Chan Smith" myList '("Michael" "Domino" "Carlos" "Smith") ) (if (setq Name1 (getstring "\nEnter 1st name: ")) (if (setq p1 (vl-string-search (strcase Name1) (strcase myName))) (progn (princ (strcat "\n" Name1 " found at position " (itoa p1) " in myName string. ")) (if (setq Name2 (getstring "\nEnter 2nd name: ")) (if (setq p2 (vl-position (strcase Name2) (mapcar 'strcase myList))) (princ (strcat Name2 " found at position " (itoa p2) " in myList. ")) (princ (strcat Name2 " not found in myList. ")) ) (princ "Canceled.") ) ) (princ (strcat "\n" Name1 " not found in myName string.")) ) (princ "\nCanceled.") ) (princ) ) Note though, I've split the if conditions into every conceivable scenario. You probably don't need to do this, as you can easily combine them using and. Quote
LISP2LEARN Posted June 9, 2011 Author Posted June 9, 2011 My bad Lee's code work just fine. I don't what I did on my first try. Thanks again guys, I learned again you. Quote
Lee Mac Posted June 9, 2011 Posted June 9, 2011 Edit: Just a query to Lee. Why are you using the vl-some and then the vl-string-search? You could either have done the vl-some with a simple eq instead, or I think the vl-position (as I've got it) would be more efficient in this case. Not sure though. If I understand correctly, the OP is not looking for string equality but rather a check that both "Jose" is present in a given string, and that any one of the names in a given list are also present in the given string. This is what I understood from the example strings in the code the OP has posted in the first post, I think its slightly clearer than the description. Quote
LISP2LEARN Posted June 9, 2011 Author Posted June 9, 2011 Yes Lee, you hit the jackpot. Sorry for my poor English and my poor lisp programming. I'm just curious on how would you guys do it in a simple manner so I can learn from it. As you all know, the simple manner for us newbies is the long way. We have to write 5 lines of code and you can do it in one or two. It's not routine that I will be using but rather an approach on how to write effective lisp routine. Thanks. Quote
Lee Mac Posted June 9, 2011 Posted June 9, 2011 You're very welcome LISP2LEARN, happy to shed some light Quote
irneb Posted June 10, 2011 Posted June 10, 2011 (edited) Sorry Lee, I think we're misunderstanding each other. My point is that inside the myList variable you have the names as individual pieces of text - so why use the vl-string-search on them when an normal eq would do exactly the same thing? So AFAICT the following are equivalent: (vl-some '(lambda ( x ) (vl-string-search x str)) '("MICHAEL" "DOMINO" "CARLOS" "SMITH")) (vl-some '(lambda ( x ) (eq x str)) '("MICHAEL" "DOMINO" "CARLOS" "SMITH")) (vl-position str '("MICHAEL" "DOMINO" "CARLOS" "SMITH")) (member str '("MICHAEL" "DOMINO" "CARLOS" "SMITH")) Edit: scratch that ... ... I just realized what you were on about! Edited June 10, 2011 by irneb Quote
Lee Mac Posted June 10, 2011 Posted June 10, 2011 Try each of the above codes on the OP's example string: "JOSE CHAN SMITH" Only the first will return T. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.