;;; seq.el --- Sequence manipulation functions -*- lexical-binding: t -*-
-;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
;; Author: Nicolas Petton <nicolas@petton.fr>
;; Keywords: sequences
-;; Version: 2.1
+;; Version: 2.14
;; Package: seq
;; Maintainer: emacs-devel@gnu.org
;; - `seq-elt'
;; - `seq-length'
;; - `seq-do'
-;; - `seq-p'
+;; - `seqp'
;; - `seq-subseq'
;; - `seq-into-sequence'
;; - `seq-copy'
;;; Code:
(eval-when-compile (require 'cl-generic))
-(require 'cl-extra) ;; for cl-subseq
+(require 'cl-lib) ;; for cl-subseq
(defmacro seq-doseq (spec &rest body)
"Loop over a sequence.
Extra elements of the sequence are ignored if fewer PATTERNS are
given, and the match does not fail."
- `(and (pred seq-p)
+ `(and (pred seqp)
,@(seq--make-pcase-bindings patterns)))
(defmacro seq-let (args sequence &rest body)
(defalias 'seq-each #'seq-do)
-(cl-defgeneric seq-p (sequence)
+(cl-defgeneric seqp (sequence)
"Return non-nil if SEQUENCE is a sequence, nil otherwise."
(sequencep sequence))
sequence)
(nreverse result)))
+(defun seq-map-indexed (function sequence)
+ "Return the result of applying FUNCTION to each element of SEQUENCE.
+Unlike `seq-map', FUNCTION takes two arguments: the element of
+the sequence, and its index within the sequence."
+ (let ((index 0))
+ (seq-map (lambda (elt)
+ (prog1
+ (funcall function elt index)
+ (setq index (1+ index))))
+ sequence)))
+
+
;; faster implementation for sequences (sequencep)
(cl-defmethod seq-map (function (sequence sequence))
(mapcar function sequence))
+(cl-defgeneric seq-mapn (function sequence &rest sequences)
+ "Like `seq-map' but FUNCTION is mapped over all SEQUENCES.
+The arity of FUNCTION must match the number of SEQUENCES, and the
+mapping stops on the shortest sequence.
+Return a list of the results.
+
+\(fn FUNCTION SEQUENCES...)"
+ (let ((result nil)
+ (sequences (seq-map (lambda (s) (seq-into s 'list))
+ (cons sequence sequences))))
+ (while (not (memq nil sequences))
+ (push (apply function (seq-map #'car sequences)) result)
+ (setq sequences (seq-map #'cdr sequences)))
+ (nreverse result)))
+
(cl-defgeneric seq-drop (sequence n)
"Remove the first N elements of SEQUENCE and return the result.
The result is a sequence of the same type as SEQUENCE.
(cl-defmethod seq-sort (pred (list list))
(sort (seq-copy list) pred))
+(defun seq-sort-by (function pred sequence)
+ "Sort SEQUENCE using PRED as a comparison function.
+Elements of SEQUENCE are transformed by FUNCTION before being
+sorted. FUNCTION must be a function of one argument."
+ (seq-sort (lambda (a b)
+ (funcall pred
+ (funcall function a)
+ (funcall function b)))
+ sequence))
+
(cl-defgeneric seq-reverse (sequence)
"Return a sequence with elements of SEQUENCE in reverse order."
(let ((result '()))
"Return a list of `(seq ...)' pcase patterns from the argument list ARGS."
(cons 'seq
(seq-map (lambda (elt)
- (if (seq-p elt)
+ (if (seqp elt)
(seq--make-pcase-patterns elt)
elt))
args)))