リストの上で集合っぽい演算
30分プログラム、その674。リストの上で集合っぽい演算を定義してみました。
みなさん、知ってます? Rubyって配列を集合みたいに扱えるんです。
>> [1,2,3] - [3,4,5] => [1, 2] [1,2,3] & [3,4,5] => [3] >> [1,2,3] | [3,4,5] => [1, 2, 3, 4, 5]
ホントの集合とは違って、もとの配列内での順番が保存されるので、わりと便利だったりします。
というわけで、こんな感じの演算を作ってみましょう。SICPの2.3.3で似たことをやっていた気がします。
使い方
(list-sub '(1 2 3) '(3 4 5)) (1 2) gosh> (list-intersect '(1 2 3) '(3 4 5)) (3) gosh> (list-union '(1 2 3) '(3 4 5)) (1 2 3 4 5)
ソースコード
#! /opt/local/bin/gosh ;; -*- mode:scheme; coding:utf-8 -*- ;; ;; list-set.scm - ;; ;; Copyright(C) 2009 by mzp ;; Author: MIZUNO Hiroki / mzpppp at gmail dot com ;; http://howdyworld.org ;; ;; Timestamp: 2009/10/08 21:02:20 ;; ;; This program is free software; you can redistribute it and/or ;; modify it under MIT Lincence. ;; (use srfi-1) (define (mem? x xs eq) (find (cut eq <> x) xs)) (define (list-intersect xs ys . args) (let-optionals* args [(eq eq?)] (filter (cut mem? <> ys eq) xs))) (define (list-sub xs ys . args) (let-optionals* args [(eq eq?)] (filter (lambda(x) (not (mem? x ys eq))) xs))) (define (list-union xs ys) (append xs ys))