Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:63266 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 74858 invoked from network); 7 Oct 2012 01:10:25 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Oct 2012 01:10:25 -0000 Authentication-Results: pb1.pair.com smtp.mail=rasmus@mindplay.dk; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=rasmus@mindplay.dk; sender-id=unknown Received-SPF: error (pb1.pair.com: domain mindplay.dk from 209.85.212.42 cause and error) X-PHP-List-Original-Sender: rasmus@mindplay.dk X-Host-Fingerprint: 209.85.212.42 mail-vb0-f42.google.com Received: from [209.85.212.42] ([209.85.212.42:62009] helo=mail-vb0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 6C/00-07529-086D0705 for ; Sat, 06 Oct 2012 21:10:25 -0400 Received: by mail-vb0-f42.google.com with SMTP id fs19so3471758vbb.29 for ; Sat, 06 Oct 2012 18:10:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type :x-gm-message-state; bh=RrTDV/lbTUc9cHFxztHn5WeLoH23Lw1NLBe4L8hfg5M=; b=BgYRoa9EFHJdVNTZ0ugxIAJOrbARPUifVorR0boG1n+YlHta2K/NS2KZEC/44laJvM 8PE40APp2g2giaBCJVWLbaeSQD3cnOhhIcvar8TG8ElIHDaE3W2SpXWQLF780nAhw/1Z kDjrWdKU2TY7/aDNAG3Kg8pV1A9lWU7DJBa0KyzXK6e6JJiQ82E1jvOLFUESlCmGf3BC Dz62PfeHuYp6KhMrUAjLA9urqi+6Jo1h35ITE6gnBaG2yhF+qkuxrj905+E6sJRKrCOS rrt2yHkPUsa3Z0ozXTCLKF00GVRR5RRcUhtlhYjn3ml5znrCOA6HtznxAXLHepmFiITJ SiZg== MIME-Version: 1.0 Received: by 10.58.59.36 with SMTP id w4mr7859631veq.26.1349572221300; Sat, 06 Oct 2012 18:10:21 -0700 (PDT) Received: by 10.58.146.103 with HTTP; Sat, 6 Oct 2012 18:10:21 -0700 (PDT) Date: Sat, 6 Oct 2012 21:10:21 -0400 Message-ID: To: internals@lists.php.net Content-Type: text/plain; charset=ISO-8859-1 X-Gm-Message-State: ALoCoQnk+nWXl3XzGC2jNavIShKJIDMwY9ijyhiA8VO4+O6QqV3Pu8Rbl5eH4N++H/CRbozJTlvF Subject: Re: Arrays which have properties of sets From: rasmus@mindplay.dk (Rasmus Schultz) Since I was the one who started this discussion, I'd like to reply to some of these points. First off, let me say - as you pointed out, when the values are unique, they are best represented as keys... however, this of course applies only to value-types, which isn't the problem, and not why I started this conversation in the first place. Objects don't work as keys. And objects do not always have a value that you can use as keys. I believe I understand the nature of arrays quite well - the situations you covered in this e-mail simply do not address the issues I was trying to tackle. I too have used the key/value duplication strategy you mentioned: array("val1" => "val1", "val2" => "val2"); I stopped doing that many years ago - what's the benefit of storing everything twice? At some point I started doing this instead: array("val1" => true, "val2" => true); You're storing the same amount of information, but now there's no confusion as far as which is the key and which is the value - and for longer keys, you don't need twice the memory. And when modifying the array, you don't have to maintain both the key and the value. Effectively this *is* a set, and as such works fine - but works only for scalar values, not for objects. > function create_set($arr) { > return array_combine($arr, $arr); > } > $set = create_set(array("val1","val2")); This seems very misleading to me, as what comes out of create_set() is not a set, but just another array - which happens to contain a set. I get what you're trying to do here, but... it just doesn't work. I don't think there's any "work-around" for not having sets, and I'm not sure if that's what you're suggesting either, but - there's no way you can educate anyone out of that issue if or when someone needs a set of objects that (per definition) do not have unique keys. You can implement a set of course, as a class - using array_search() internally in the class, you can check if a given value (or object) is present in the set. I've done this on one occasion, and it actually performs acceptably for a small (~1000) set of objects, so it's not that this problem represents a roadblock by any means. But it is a solution with obvious performance deficiencies and trade-offs... > From: Adam Jon Richardson > To: internals@lists.php.net > Cc: > Date: Thu, 4 Oct 2012 12:48:53 -0400 > Subject: Arrays which have properties of sets > A while back, there was a thread discussing adding a specific function > for removing elements from an array by value. Rasmus L. noted that > when the values are unique, they would be better represented as keys: > > The problem is that it is a rather unusual thing to do. I don't mean > > removing an element, that is very common, but you are implying that you > > know you don't have duplicates and you want a fast way to remove an > > element by value in that case. To me that means you built your array > > badly. If the values are unique then they should be the keys, or at > > least a representation of the value should be the key such that you > > don't need to scan the entire hash for the element when you need to > > access it. And removal is just like any other access. > When I come across situations where an array's properties match those > of a set, I create array "sets" by duplicating keys and values: > array("val1" => "val1", "val2" => "val2"); > This approach has several benefits: > - Form the union of values using the "+" operator (which forms unions > through use of keys) > - Fast, easy removal of values through unset (e.g., unset($elements["val1"])) > - Standard handling of values in for loops: > for ($elements as $element) { > echo $element; > } > Writing a userland function to create array sets from > numerically-indexed arrays (avoiding the duplication of typing the key > and value) is indeed trivial: > function create_set($arr) { > return array_combine($arr, $arr); > } > $set = create_set(array("val1","val2")); > However, I find that the use of array sets is very common and helpful > to me, and I see many situations where a developer would have been > better served by leveraging the key to store the value. I suspect many > PHP users don't understand the nature of PHP arrays. I'm wondering if > adding a function (or language construct) for creating array sets > would prove helpful (just because of the vast amount of code which > could make use of it) and facilitate the education of developers so > they might better leverage the benefits of the underlying hash map > structure when their array is essentially a set and they wish to > perform operations such as removing an item by value. > Ada