Работа с несколькими строками для создания строки - PullRequest
0 голосов
/ 02 ноября 2019

С result, установленным на ("cypueihajytotrdkgzxfqplbwn" . "cypueihajytomrdkgzxfqplbwn"), приведенный ниже код дает желаемый результат выбивания несовпадающего символа "t": "cypueihajytordkgzxfqplbwn"

Без concat результат возвращается в виде спискаиз целых чисел, представляющих значения ASCII каждого символа в строке. Но сами входные значения рассматриваются оценщиком как строки. Поэтому я теряю строгость result в алгоритме (возможно, потому что mapcar* рассматривает каждую строку как список символов, а символы - просто целые числа).

Мой вопрос - есть лиидиоматический способ поддержания строгости переменной вместо необходимости ее принудительного применения в конце с помощью concat или apply #'string. ИМХО concat делает код немного шумным (er).

(print (concat (mapcar #'car (cl-remove-if-not 
        (lambda (r) (equal (car r) (cdr r)))
        (mapcar* #'cons (car result) (cdr result))))))

1 Ответ

2 голосов
/ 02 ноября 2019

Основным типом данных в Emacs Lisp является список. Emacs предоставляет множество функций (таких как car и cdr) для обработки списка, и легче работать со списком, чем с массивом (включая вектор и строку). Например, функция mapcar возвращает список, даже если вы передаете ему строку или вектор:

(mapcar #'identity "hello")
;; => (104 101 108 108 111)

(mapcar #'identity [1 2 3])
;; => (1 2 3)

Нередко преобразовать массив в список, обработать список, а затем преобразовать обратно в массив. Помимо concat и string, вы также можете построить строку с mapconcat.

Для вашего кода вы используете функцию, похожую на mapcar, три раза, я думаю, что для следующего используется только один разчитать легче

(let ((result (cons "cypueihajytotrdkgzxfqplbwn"
                    "cypueihajytomrdkgzxfqplbwn")))
  (concat
   (delq
    nil
    (cl-mapcar
     (lambda (c1 c2) (and (= c1 c2) c1))
     (car result) (cdr result)))))
;; => "cypueihajytordkgzxfqplbwn"

При настойчивом подходе код становится еще чище

(let ((result (cons "cypueihajytotrdkgzxfqplbwn"
                    "cypueihajytomrdkgzxfqplbwn")))
  (cl-loop for x across (car result)
           for y across (cdr result)
           when (= x y)
           concat (string x)))
;; => "cypueihajytordkgzxfqplbwn"
...