Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Set operations
- X-seq: zsh-workers 25763
- From: Phil Pennock <zsh-workers+phil.pennock@xxxxxxxxxxxx>
- To: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- Subject: Re: Set operations
- Date: Sat, 27 Sep 2008 18:50:15 -0700
- Cc: Zsh hackers list <zsh-workers@xxxxxxxxxx>
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=d200807; d=spodhuis.org; h=Received:Date:From:To:Cc:Subject:Message-ID:Mail-Followup-To:References:MIME-Version:Content-Type:Content-Disposition:In-Reply-To; b=2fjscofcVXYQdeFQMXOHMNy+wd+2XZk8OLRyPT6xGRDcE4NIFaRRrvomkEpD0mUQEiYLxNG1L2DfG8BLcnTYkBdE8df3ss9Bh8gDfYWUqG+1Ui4YiASv+OO/8izubpa1PpfAE3u7ClL4QksbFDAkySVJqWWpRW7TZE1ZWlDUEnI=;
- In-reply-to: <20080927214826.2f11e7b0@pws-pc>
- Mail-followup-to: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>, Zsh hackers list <zsh-workers@xxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <20080927090225.GA61785@xxxxxxxxxxxxxxxxxxxx> <20080927214826.2f11e7b0@pws-pc>
On 2008-09-27 at 21:48 +0100, Peter Stephenson wrote:
> I appreciate there's a problem here, but I'm a little bit lost as to
> what exactly you're after. Do you mean you'd like the "|" in the (j,|,)
> to be treated as a pattern character, but the characters substituted
> from the paramater named by b not to be expanded?
What I was after wasn't anywhere near as good as what you provided.
I was thinking that just as we have (q) to apply shell quoting, we
should have a flag to escape pattern characters, which would have
laboriously allowed me to do what you've just done much more easily by
avoiding the whole problem. :)
Escape+join+parse_that vs only-parse-the-join
> If I'm not following, you may want white chococlate mousse followed by a
> cappuccino.
No, but my wife would love that.
> Anyway, I'm not sure why I didn't do this ages ago, it makes testing
> lists of alternatives vastly easier.
Oh good, that's two different uses for it which means it's definitely
more broadly helpful and it's not just me. *phew* Thanks.
Okay, the two attachments provide the resulting clean set operations,
with a stupid bug fixed and the intersection operations cleaned up, and
the Test file for these.
I'm not attached to any names, but I put the first file in
Functions/Misc/load_dataset and the test file depends upon that. I just
named load_dataset "load_dataset-post-20080927.zsh" to remind anyone
using this that it uses your new (~) parameter expansion option.
I'm also not attached to this code, since messing with 'let' to have zsh
understand sets in arithmetic context is more appealing to me, every
time I think about it. But the two approaches should be mutually
compatible and this is the one I opted for.
And I *just* realised that I needed set_equal, which sets $?, to provide
a clean way to test for equality, since not only are the sets not
maintained in sorted order, but the need to deal with arbitrary data
would lead to bugginess. *sigh* Arithmetic with no equality tests.
What was I thinking? Done.
Do people think superset/subset/strict_superset/strict_subset would be
useful too?
-Phil
# provide functions for manipulating unique lists as sets.
function newset {
setopt local_options no_ksh_arrays
local name="$1"; shift
typeset -gUa $name
set -A $name "$@"
}
function copyset_tofrom {
setopt local_options no_ksh_arrays
local new="$1" old="$2"
typeset -gUa $new
set -A $new "${(P@)old}"
}
function copyset_fromto { copyset_tofrom "$2" "$1" }
function set_add_new {
setopt local_options no_ksh_arrays
local new="$1" a="$2" b="$3"
typeset -gUa $new
set -A $new "${(P@)a}" "${(P@)b}"
}
function set_add_in {
setopt local_options no_ksh_arrays
local name="$1" b="$2"
set -A $name "${(P@)name}" "${(P@)b}"
}
function set_add_print {
setopt local_options no_ksh_arrays
local a="$1" b="$2"
typeset -Ua tmp
tmp=("${(P@)a}" "${(P@)b}")
print -r -- ${(q)tmp}
}
function set_subtract_new {
setopt local_options no_ksh_arrays
local new="$1" a="$2" b="$3"
typeset -gUa $new
set -A $new "${(P@)a:#${(P~j,|,)b}}"
}
function set_subtract_in {
setopt local_options no_ksh_arrays
local name="$1" b="$2"
set -A $name "${(P@)name:#${(P~j,|,)b}}"
}
function set_subtract_print {
setopt local_options no_ksh_arrays
local a="$1" b="$2"
typeset -Ua tmp
tmp=("${(P@)a:#${(P~j,|,)b}}")
print -r -- ${(q)tmp}
}
function set_intersection_new {
setopt local_options no_ksh_arrays
local new="$1" a="$2" b="$3"
typeset -gUa $new
set -A $new "${(@PM)a:#${(P~j,|,)b}}"
}
function set_intersection_in {
setopt local_options no_ksh_arrays
local name="$1" b="$2"
set -A $name "${(@PM)name:#${(P~j,|,)b}}"
}
function set_intersection_print {
setopt local_options no_ksh_arrays
local a="$1" b="$2"
typeset -Ua tmp
tmp=("${(@PM)a:#${(P~j,|,)b}}")
print -r -- ${(q)tmp}
}
function set_union_new { set_add_new "$@" }
function set_union_in { set_add_in "$@" }
function set_union_print { set_add_print "$@" }
function set_difference_new { set_subtract_new "$@" }
function set_difference_in { set_subtract_in "$@" }
function set_difference_print { set_subtract_print "$@" }
function set_symmetric_difference_new {
setopt local_options no_ksh_arrays
local new="$1" a="$2" b="$3"
typeset -gUa $new
set -A $new "${(P@)a:#${(P~j,|,)b}}" "${(P@)b:#${(P~j,|,)a}}"
}
function set_symmetric_difference_in {
setopt local_options no_ksh_arrays
local name="$1" b="$2"
set -A $name "${(P@)name:#${(P~j,|,)b}}" "${(P@)b:#${(P~j,|,)name}}"
}
function set_symmetric_difference_print {
setopt local_options no_ksh_arrays
local a="$1" b="$2"
typeset -Ua tmp
tmp=("${(P@)a:#${(P~j,|,)b}}" "${(P@)b:#${(P~j,|,)a}}")
print -r -- ${(q)tmp}
}
function set_insert_list {
setopt local_options no_ksh_arrays
local name="$1"; shift
set -A $name "${(P@)name}" "$@"
}
function set_remove_list {
setopt local_options no_ksh_arrays
local name="$1"; shift
set -A $name "${(P@)name:#${(~j,|,)@}}"
}
function set_equal {
setopt local_options no_ksh_arrays
local a="$1" b="$2"
[[ "${${(P@oq)a}}" == "${${(P@oq)b}}" ]]
}
# Is there a way to print the variable, in the style of "typeset -p",
# but showing the -U unique-flag?
%prep
fpath=(../Functions/Misc)
autoload load_dataset
load_dataset
%test
newset x a b c d
newset y c d e f
copyset_tofrom z x
print -l "$x" "$y" "$z"
0:Testing basic set creation
>a b c d
>c d e f
>a b c d
set_add_print x y
set_add_in z y
print $z
set_add_new z x y
print $z
0:Testing set addition (union)
>a b c d e f
>a b c d e f
>a b c d e f
set_subtract_new z x y
print $z
copyset_fromto x z
set_subtract_in z y
print $z
set_subtract_print x y
set_subtract_print y x
0:Testing set subtraction (asymmetric difference)
>a b
>a b
>a b
>e f
set_intersection_new z x y
print $z
copyset_tofrom z x
set_intersection_in z y
print $z
set_intersection_print x y
0:Testing set intersection
>c d
>c d
>c d
set_symmetric_difference_new z x y
print $z
copyset_tofrom z x
set_symmetric_difference_in z y
print $z
set_symmetric_difference_print x y
set_symmetric_difference_print y x
0:Testing set symmetric difference
>a b e f
>a b e f
>a b e f
>e f a b
set_insert_list y 'a|b' '*'
set_remove_list x d
print -l "$x" "$y"
0:Testing basic set item addition and removal
>a b c
>c d e f a|b *
set_intersection_print x y
set_symmetric_difference_print x y
set_union_print x y
set_difference_print x y
set_difference_print y x
0:Testing set resilience to meta characters
>c
>a b d e f a\|b \*
>a b c d e f a\|b \*
>a b
>d e f a\|b \*
newset z b c a
set_equal x z
0:Testing set equality
newset z a 'b c'
set_equal x z
1:Testing set inequality
Messages sorted by:
Reverse Date,
Date,
Thread,
Author