3

How can I remove a certain character from a string in Nyquist (which is very similar to xlisp) and have the result returned?

I want to count how many "A" there are in a string like "ABBAAAABBBAABAAAB". (Yes, there are only 'A's and 'B's in the string.)

Since there is no (count) function in Nyquist I tried something like

(length (remove #\B mystring))

or

(length (remove #\B mystring :test equal))

But it doesn't work.

Forgetting the character count for a moment, how can I remove the 'B's from the string?

David Costa
  • 1,738
  • 18
  • 33

2 Answers2

2

Will there always be only As and Bs in the string? If not, you might want to do something like

(remove #\A yourstring :test-not 'char=)

According to the XLISP reference for remove, the Nyquist remove doesn't deal with strings, only lists. You need to convert a string to a list in order to operate on it this way, but there's no coerce either. It's a touch hacky, but the easiest way around it I see is to stream a string and read-char it. This will produce a list of chars that you can then manipulate with remove.

(defun string->list (a-string)
  (let ((collector nil)
        (stream (make-string-input-stream a-string)))
    (dotimes (c (length a-string) (reverse collector))
      (setf collector (cons (read-char stream) collector)))))

It should now be possible to

(remove #\A (string->list yourstring) :test-not 'char=)
Inaimathi
  • 13,853
  • 9
  • 49
  • 93
  • Unluckily it doesn't work. "(setf yourstring "ABBAABABCCCCBBCCCCAAA") (print (remove #\A yourstring :test-not 'char=))" results in "error: bad argument type - "ABBAABABCCCCBBCCCCAAA" Function: # Arguments: #\A "ABBAABABCCCCBBCCCCAAA" :TEST-NOT CHAR= 1> " – David Costa Jan 28 '12 at 16:01
  • @David Costa - did you try it with `'equal`? – Inaimathi Jan 28 '12 at 16:58
  • Same error. The interpreter says mystring is of the wrong type. And in effect there are no strings in the examples. – David Costa Jan 28 '12 at 17:24
  • @David Costa - Hm. Good point; I had tested this in Common Lisp (where your original works fine, by the way). If the error is about the type of `mystring`, it might be that strings are represented differently than standard sequences in XLISP. Is there a `coerce` function or similar you could use to convert a `string` to a list of `char`s? – Inaimathi Jan 28 '12 at 18:27
  • Apparently there is no coerce function in the reference. – David Costa Jan 29 '12 at 11:54
  • @David Costa - Wow. That's a pretty gimped Lisp implementation now that I really look at it; you don't even have a proper CL Loop to work with. Try the definition of `string->list` I just posted. `(remove #\A (string->list yourstring) :test-not 'char=)` should work (I didn't test it as I don't have a Nyquist interpreter here, so it may need some fine tuning). – Inaimathi Jan 29 '12 at 14:34
1

I see this is an old question, but since it has over 800 views, it's perhaps worth having the simple answer:

(defun remove-char (character sequence)
  (let ((out ""))
    (dotimes (i (length sequence) out)
      (setf ch (char sequence i))
      (unless (char= ch character)
        (setf out (format nil "~a~a" out ch))))))

(setf mystring "ABBAABABCCCCBBCCCCAAA")
(remove-char #\B mystring) ;returns "AAAACCCCCCCCAAA"
Steve Daulton
  • 176
  • 1
  • 4