| |||||||||||
| |||||||||||
subset a list Posted by gmeyer (gmeyer), 16 October 2003 Hi Graham,I was wondering if there is a quick way of finding out if a list of values is a subset of another list of values? Something along these lines would be nice...but of course this doesnt work! @biglist=('one', 'two', 'three'); @smallist=('one','three'); $true = grep (/@smallist/i, @biglist); if ($true) { print "\nYes the smallist is a subset of biglist") } Great forum guys. Gordon Posted by gmeyer (gmeyer), 16 October 2003 Just noticed that this should be in the perl programming language section of course!..sorry.Posted by John_Moylan (jfp), 16 October 2003 I may be talking rubbish. (believe me theres a good chance of this)..butCould you flatten the arrays and test the strings against each other? Code:
Posted by admin (Graham Ellis), 16 October 2003 Why do the most interesting questions get posted while I'm on an intercontinentyal flight? ![]() I've got some ideas, but too tired to put them down in goon English tonight .... I'll follow up further in the morning. Posted by admin (Graham Ellis), 17 October 2003 Flattening the arrays would work in some special circumstances - you would need both lists to be in the same order, and the items matching to follow directly after one another in the bigger list, amongst other constraints.There's no one-liner to do what you want, Gordon (unless you make it a very long line with lots of ; s in it!). Here is a "quick and dirty" fix: Code:
I've run this, fiddled the data, run it again .... it works fine. In effect, you have a loop within a loop which is not going to be efficient, but at least I've had grep use "eq" rather that "=~", so that you're not doing huge numbers of regular expression check. Once you set $allin to 0 in my example, you know your test has failed so there's no point in carrying on - thus, you can identify failed matches quicker using last: Code:
Now - you ask if there's a quick way of finding out if one list is in another, but I give you a solution that's a loop, and within it you have a grep which has an embedded loop checking all elements. Perhaps not your definition of quick. If you have a whole series of smalllists to check against one biglist, or if both lists contain quite a lot of elements, you might like to use the power of a hash to set up a table of elements that exist in the big list. Here's what I mean: Code:
The testing has now come down to a single simple loop that doesn't have to go through all the elements of another list. Neat trick, learnt from the masters in books like the Perl cookbooks, and something we employ ourselves in quite a number of our own scripts. Posted by gmeyer (gmeyer), 17 October 2003 Thx guys,I have gone for the final solution transposing into a hash. Posted by Custard (Custard), 19 October 2003 Hiya,I don't want to seem 'clever' but as a matter of interest, I was reading a book 'algorithms in perl' last night that had a whole section on sets. One thing I saw that would be most useful in your case would be ths hash slice method. So, to create the set you (could) use @set{ 'one','two','three' } = (); or @set{ @array } = (); This defines a hash of undef's, which is quicker. Also the search loop will have to test for exists $set{ $item }, which is also quicker. Aparrently if you define undef as a value in a hash, perl doesn't have to add a value, and using exists doesn't have to retrieve the value. Also, undef is a reference to a single object, and if you had used '1' then each '1' would be a separate object. It's also a one liner. Everyday's a school day with perl... hth Bruce PS. I've not tried it yet ;-o) Posted by admin (Graham Ellis), 19 October 2003 Neat thought .... yes .... I'll have to try that sometime. I would suggest that anyone using undef'd members of a hash adds a few comments to their source!This page is a thread posted to the opentalk forum
at www.opentalk.org.uk and
archived here for reference. To jump to the archive index please
follow this link.
|
| ||||||||||
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho |