https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112015-06-28T17:03:40ZRuby Issue Tracking SystemRuby master - Feature #11315: [PATCH] Add Array#^ for parity with other set-like operations.https://redmine.ruby-lang.org/issues/11315?journal_id=531392015-06-28T17:03:40Z0x0dea (D.E. Akers)0x0dea+redmine@gmail.com
<ul><li><strong>File</strong> <a href="/attachments/5348">array_xor_vodka.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/5348/array_xor_vodka.patch">array_xor_vodka.patch</a> added</li></ul><p>The original implementation did not correctly handle the case of repeated elements occurring an even number of times in the second array. Attached is an updated version which does not present this defect, courtesy of <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/269">@apeiros (Stefan Rusterholz)</a> and his 50-proof vodka.</p> Ruby master - Feature #11315: [PATCH] Add Array#^ for parity with other set-like operations.https://redmine.ruby-lang.org/issues/11315?journal_id=531402015-06-28T17:10:02Z0x0dea (D.E. Akers)0x0dea+redmine@gmail.com
<ul><li><strong>File</strong> <a href="/attachments/5349">array_xor_recycle_seen.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/5349/array_xor_recycle_seen.patch">array_xor_recycle_seen.patch</a> added</li></ul><p>I forgot to recycle the <code>seen</code> hash. This last fix should finalize the patch, unless there is some very clever way to XOR two arrays without requiring two tables or a second pass through one of the arrays.</p> Ruby master - Feature #11315: [PATCH] Add Array#^ for parity with other set-like operations.https://redmine.ruby-lang.org/issues/11315?journal_id=531412015-06-28T17:57:12Z0x0dea (D.E. Akers)0x0dea+redmine@gmail.com
<ul><li><strong>Tracker</strong> changed from <i>Bug</i> to <i>Feature</i></li></ul> Ruby master - Feature #11315: [PATCH] Add Array#^ for parity with other set-like operations.https://redmine.ruby-lang.org/issues/11315?journal_id=531432015-06-29T05:05:31Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p><code>st_update</code> does lookup/replace/delete/insert in the callback at once.<br>
And your patches are broken, necessary spaces are stripped.</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/array.c b/array.c
index 072e30d..737afa3 100644
</span><span class="gd">--- a/array.c
</span><span class="gi">+++ b/array.c
</span><span class="p">@@ -4200,6 +4200,14 @@</span> rb_ary_or(VALUE ary1, VALUE ary2)
return ary3;
}
<span class="gi">+static int
+ary_hash_xorset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
+{
+ if (existing) return ST_DELETE;
+ *key = *value = (VALUE)arg;
+ return ST_CONTINUE;
+}
+
</span> /*
* call-seq:
* ary ^ other_ary -> new_ary
<span class="p">@@ -4228,15 +4236,9 @@</span> rb_ary_xor(VALUE ary1, VALUE ary2)
result = ary_make_hash(ary1);
for (i = 0; i < RARRAY_LEN(ary2); ++i) {
<span class="gd">- elt = (st_data_t)RARRAY_AREF(ary2, i);
- if (st_lookup(RHASH_TBL_RAW(seen), elt, 0)) continue;
- st_update(RHASH_TBL_RAW(seen), elt, ary_hash_orset, elt);
- if (st_lookup(RHASH_TBL_RAW(result), elt, 0)) {
- st_delete(RHASH_TBL_RAW(result), &elt, 0);
- }
- else {
- st_update(RHASH_TBL_RAW(result), elt, ary_hash_orset, elt);
- }
</span><span class="gi">+ elt = (st_data_t)RARRAY_AREF(ary2, i);
+ if (!st_update(RHASH_TBL_RAW(seen), elt, ary_hash_orset, elt))
+ st_update(RHASH_TBL_RAW(result), elt, ary_hash_xorset, elt);
</span> }
ary3 = rb_hash_values(result);
</code></pre>