不使用set更新列表! - 计划

时间:2016-04-07 15:13:13

标签: list scheme

关于在不使用set!

的情况下将列表保留在内存中的问题

我定义了一个初始空列表,

(define database (list))

然后我有这个程序检查密码是否正确并将该对添加到列表中。

(define (set-pass l)
  (if (pair? l)
    (if (check-pass (second (last l)))
      (add-to-list l) 
      "password does not meet policy requirements"
      )
  "invalid input"
  )
)

添加到列表的过程:

(define (add-to-list l)
  ;(append database l)
  ;implement this.
  )

问题是,我必须多次调用此程序:

(set-pass '('john '(X p c F z C b Y h 1 2 3 4 : :)))
(set-pass '('john '(X p c F z C b Y : 1 2 3 4 : :)))
(set-pass '('john '(X p c F z C b : : 1 2 3 4 : :)))

我实现了程序add-to-list,就像我正在调用set-pass一次(如上所示附加),但如果我多次调用它,我找不到实现的方法。我尝试了一些提及hereherehere的内容。但我无法实现我想要的。那我怎么能这样做呢?

1 个答案:

答案 0 :(得分:1)

通过将数据库作为变量来实现这一功能:

# Switch statement loops over each line in the file
switch -regex (get-content data.txt)
{
    # Makes sure that the line matches
    '^[0-9]+-[0-9]+-[0-9]' {
        # split the line with multiple assignement & type constraint
        [datetime] $timestamp, $data1, $data2 = $_ -split ' . '
        # Build the result object
        [PSCustomObject] @{
            timestamp = $timestamp
            data1 = $data1
            data2 = $data2
        }
    }
}

其他功能(移除等)的工作方式与根据操作改变结构重复的方式相同。

您还可以使用(let loop ((input (read-line)) (database '())) (display (format "inserting ~a\n" input)) (loop (read-line) (cons input database))) 更新列表。虽然set-cdr!会改变符号指向的内容,但set!会改变一对符号set-cdr!。因为它需要成对,所以你需要让第一个元素成为一些虚拟数据:

cdr

第二个你允许突变的猫是从包里出来的,所有突变都可用。例如。如果提供了(define database (list "head")) (define (add element) (let ((tmp (cdr database))) (set-cdr! database (cons element tmp)))) (define (delete element) (let loop ((prev database) (cur (cdr database))) (cond ((null? cur) #f) ((equal? (car cur) element) (set-cdr! prev (cdr cur))) (else (loop cur (cdr cur)))))) (define (get) (cdr database)) (add 1) (add 2) (add 3) (get) ; ==> (3 2 1) (delete 2) (get) ; ==> (3 1) ,您可以使用闭包创建一个可变对象,如果提供set! / set-car!,您可以使用框获取可变绑定。