Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Random question

Name: Anonymous 2009-11-25 21:52

Using c++, I have a string vector containing thousands of elements. I know I can erase a specific element using:

vectorName.erase(remove(vectorName.begin(),vectorName.end(),"whatever"),vectorName.end());

In that example it would get rid of any vector elements that equaled "whatever".

I'm looking to erase certain elements if anywhere in that element it has a certain combination of letters. In my case, I want to erase any URLs that make it into the vector, so I would erase any element that contained "http" or "www" in it.

I tried googling this, but I have no clue what to look for. Can anyone offer their expertise? Is there a one line solution using vectorName.erase()?

Name: Anonymous 2009-11-28 7:59

>>13
Here's a more generic solution in CL:

(defun remove-badwords (sequence badwords)
  (remove-if #'(lambda (x)
                 (dolist (s badwords)                  
                   (when (search s x :test #'equalp)
                     (return t))))
             sequence))

CL-USER> (remove-badwords #("abcdef" "http://dis.4chan.org/prog/" "..A..." "huh") '("http" "www" "..."))
#("abcdef" "huh")

Another solution if the badwords are hardcoded, is to replace that DOLIST with (or (search ...) (search ...) (search ...), or just write a macro which does that for you:


(defmacro do-log (op list item &body template)
  `(,op ,@(mapcar #'(lambda (x)
                      `(let ((,item ,x))
                         ,@template))                 
                  list)))

(do-log or ("http" "www" "...") s
  (search s "http://dis.4chan.org/prog/" :test #'equalp))

;;; expands to
(OR
 (LET ((S "http"))
   (SEARCH S "http://dis.4chan.org/prog/" :TEST #'EQUALP))
 (LET ((S "www"))
   (SEARCH S "http://dis.4chan.org/prog/" :TEST #'EQUALP))
 (LET ((S "..."))
   (SEARCH S "http://dis.4chan.org/prog/" :TEST #'EQUALP)))

;;; which is fine, but not perfect, a better solution would be:

(defmacro do-log (op list item &body template)
   `(,op ,@(mapcar #'(lambda (x)                      
                       (eval `(let ((,item ,x)) ,@template)))
                   list)))

(do-log or ("http" "www" "...") s
  `(search ,s "http://dis.4chan.org/prog/" :test #'equalp))

; expands to

;=> (OR (SEARCH "http" "http://dis.4chan.org/prog/" :TEST #'EQUALP)
;       (SEARCH "www" "http://dis.4chan.org/prog/" :TEST #'EQUALP)
;       (SEARCH "..." "http://dis.4chan.org/prog/" :TEST #'EQUALP))

;;; Which is exactly the desired expansion, but it uses EVAL at macroexpansion time, which might be considered a bit distateful. I also wrote a solution which involves nested backquotes, but it's a bit hard to read compared to the EVAL one, so I'm not including it here.
;;; REMOVE-BADWORDS using hardcoded badwords:
(defun remove-badwords (sequence)
  (remove-if #'(lambda (x)
         (do-log or ("http" "www" "...") s
           `(search ,s x :test #'equalp)))
         sequence))

;;; These were simple, and fun exercises, but in a real application, one might want to just use a regular expression:
(require :cl-ppcre) ; or (asdf:oos 'asdf:load-op '#:cl-ppcre)
(defun remove-badwords (sequence badwords)
  (remove-if #'(lambda (x) (cl-ppcre:scan "http|www" x)) sequence))

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List