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()?
>>1 vectorName = [s for s in vectorName where "http" not in s and "www" not in s]
Oh wait, sepples...
for (std::vector<std::string>::iterator i = vectorName.begin(); i != vectorName.end(); ++i)
if (i->find("http") != -1 || i->find("www") != -1)
vectorName.erase(i--);
// If either of the arguments is a reference it can't be used with ptr_fun/bind2nd
// because the workings of binder2nd would form a reference to a reference, which is
// illegal.
bool contains(string s, string t) {
return s.find(t) != string::npos;
}
template<class A, class B, class Arg>
struct unary_or_function: unary_function<Arg, bool> {
unary_or_function(A const& f, B const& g)
: f(f), g(g) { }
>>13
In scheme, I would have probably just used a list instead of a vector so (require srfi/13)
(filter (lambda (x) (or (string-contains x "http")
(string-contains x "www")))
the-list)
Presumably, I could write an equivalent procedure for vectors, but it would take me a little longer to think of a solution
Name:
Anonymous2009-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:
;;; 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))
In the last function, one should remove the badwords keyword as it's hardcoded. Another thing, the SEPPLES version seems to use erase, which is a destructive operation. If that is desired, references to REMOVE-IF should be replaced with DELETE-IF in the code examples in >>15, and the original sequence should be SETF'd with the result of that DELETE-IF.
>>17
What's the matter? TOO ABSTRACT FOR YOU?
Lisp solutions which were presented were 2,3,6,9 lines long each. Subtract 1 or 2 lines from each (as appropriate) if you don't count function/macro definition. They worked, on lists and arrays, and had different performance characteristics, leaving you a wide choice.
>>20
That's a fun trick, but treating strings as symbols pollutes the current package with random symbols, it's also limited to entire words separated by spaces, as opposed to badwords which are part of a larger string.
>>23
Lisp knows better than that. >>20 works with both strings and symbols. Here's an example
(defun word (string)
(string-downcase (string-trim '(#\Space)
(string string))))