Jump to content

What is the shortest way to compare 2 WireArrays?


Go to solution Solved by Soma,

Recommended Posts

...and ideally fastest way.

Where "equal" means that both arrays have the same set of elements, while order may be different.

Straightforward way is to use double foreach, but I'm wondering if there is more elegant way with selectors and PW API.

Link to post
Share on other sites
// could be this.
if(count(array_diff($array_1, $array_2)) === 0)) {
    echo "identical"
}

Others will come up with other clever ideas I think

It don't need to sort(), edited the post

don't take this as an example, 

Edited by Martijn Geerts
  • Like 4
Link to post
Share on other sites
// could be this.
if(count(array_diff($array_1, $array_2)) === 0)) {
    echo "identical"
}

There is one ) too much, but it also gives a 500 Internal server error

edit: echo "identical" was missing ; that caused the 500 Internal error. It seems to work find when you remove on ) and add a ;

// could be this.
if(count(array_diff($array_1, $array_2)) === 0) {
echo "identical";
}

This one is not that short but will do the job

$wa1 = $pages->find('template=foo');
$wa2 = $pages->find('template=bar');
$wa3 = $pages->find('template=foo|bar,sort=name');
$wa4 = $pages->find('template=foo|bar,sort=-name');
$wa5 = $pages->find('template=foo|bar|foobar');

echo "compair: wa1 and wa2 = ";
echo count($wa1) >= count($wa2) ? count($wa1->not("id=$wa2")) : count($wa2->not("id=$wa1"));
echo "<br>";

echo "compair: wa3 and wa4 = ";
echo count($wa3) >= count($wa4) ? count($wa3->not("id=$wa4")) : count($wa4->not("id=$wa3"));
echo "<br>";

echo "compair: wa3 and wa5 = ";
echo count($wa3) >= count($wa5) ? count($wa3->not("id=$wa5")) : count($wa5->not("id=$wa3"));
echo "<br>";

Output (where 0 means identical)

compair: wa1 and wa2 = 3
compair: wa3 and wa4 = 0
compair: wa3 and wa5 = 9

(I have 3 pages with template foo, 3 with template bar and 3 with template foobar)

Edited by Raymond Geerts
  • Like 2
Link to post
Share on other sites

Sorry Martijn, this one also outputs false while they are idential

$wa3 = $pages->find('template=foo|bar,sort=name');
$wa4 = $pages->find('template=foo|bar,sort=-name');

sort($wa3);
sort($wa4);

echo ($wa3 == $wa4) ? "true" : "false";

Altough the fly-thingies images are identical indeed :)

Link to post
Share on other sites

Thank you guys! With correction (see http://us1.php.net/manual/en/function.array-diff.php) this seem to be the best option:

$a1 = $array_1->explode('id');
$a2 = $array_2->explode('id');
if((count(array_diff($a1, $a2)) + count(array_diff($a2, $a1)))===0) echo 'identical';

Would be great to see in PW core something like $a1->isIdentical($a2) as such kind of comparison is not rare (at least in my projects) !

Link to post
Share on other sites

Works too (with WireArray/PageArray) the trick is to add the two arrays together, PW will remove dublicates. So you can compare count after "merging", if result is different they're not identical.

$orig = clone($a1);
if($a1->add($a2)->count == $orig->count) $is = "identical";

Edit: hmm, too soon. small correction, needs a clone to keep original array in memory

  • Like 4
Link to post
Share on other sites

Just trying and while it works at first with two identical arrays, throwing in some different sorting it doesn't seem to work. Hmm.

Edit: I think it should work, but got some wierd result could be me aswell :) I think there's another simple way when dealing with page arrays but will test some.


Edit: Ah, I combined limit=N with sort... :)

  • Like 1
Link to post
Share on other sites
  • Solution

Sorry, me again.

This works too and may best option with page arrays where you have an id.

if("{$a1->sort('id')}" == "{$a2->sort('id')}") echo "identical";

Sort them by id first and put into quotes to make them both a string, if string is same they were identical.

To go further, you could extend the PageArray with a new method. This can be done with a simple hook. For example in your templates init:

wire()->addHook("PageArray::compare", null, function($event){
    $a1 = $event->object;
    $a2 = $event->arguments(0);
    $event->return = "{$a1->sort('id')}" == "{$a2->sort('id')}";
});

Then you can use it everywhere in your templates like this

if($a1->compare($a2)) echo "identical";
If you the hook to an autoload module like the HelloWorld.module you could use this method throughout PW.
  • Like 6
Link to post
Share on other sites

// This code should be in the docs, not because of this context,

// but because of the collaboration between $event->object and $event->arguments(0)

wire()->addHook("PageArray::compare", null, function($event){

$a1 = $event->object;

$a2 = $event->arguments(0);

$event->return = "{$a1->sort('id')}" == "{$a2->sort('id')}";

});

  • Like 1
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By prestoav
      Hi all,
      I could have sworn I used to be able to use the site generic 'title' field as a sub field of a repeater field. However I've tried to do this on two 3.0.165 sites recently and, while it will add the title field in the repeater field setup, it wont save the repeater title sub field's content when the repeater is used in a page template and edited.
      It;'s not a big issue but I wondered if this was a known restriction?
    • By Guy Incognito
      I seem to be running into a repeated fatal error in a fresh PW install version 3.0.148. I can't quite put my finger on the pattern but it seems to be around deleting image fields or removing images from certain image fields.
      This is the trace from the log generated by trying to save a page and delete an image from an image field:
      Fatal Error: Uncaught Error: Cannot access protected property Pageimage::$original in /wire/core/PageimageVariations.php:256 Stack trace: 1. /wire/core/Pageimage.php(1327): PageimageVariations->getInfo() 2. /wire/core/Wire.php(386): Pageimage->___isVariation() 3. /wire/core/WireHooks.php(823): Wire->_callMethod() 4. /wire/core/Wire.php(450): WireHooks->runHooks() 5. /wire/core/Pageimage.php(1369): Wire->__call() 6. /wire/core/Pageimage.php(399): Pageimage->getOriginal() 7. /wire/core/WireData.php(333): Pageimage->get() 8. /wire/core/PageimageVariations.php(256): Pro Line 256 of /wire/core/PageimageVariations.php Earlier in the day I was experimenting with custom fields for images for the first time and kept running into this error, thinking it was me using this feature wrong and not having time to read up I deleted the custom image fields template and went about my business. So now I don't know if I triggered an issue or whether it was never related to the custom image fields in the first place?
      Any ideas?
    • By BitPoet
      Since I'm doing a lot of detailed logging in our internal PW-based systems, that has become a bit of a bottleneck under heavy load and I was missing a centralized view with the growing number of separate PW instances. So I dug into the core a bit, namely WireLog.php and FileLog.php as well as ProcessWire.php. I managed to whip up my own WireLogDatabase and DbLog classes mimicking the behaviour of the regular logging classes, but not without a little bit of tweaking to the ProcessWire class itself to replace the regular logger. Now I'm logging to a MySQL server instead of plain files and ProcessLogger works smoothly with it without tweaking.
      I thought it would be shame to keep this all to myself, but a release-worthy version would need or could benefit from:
      a bit of polishing in regards to error handling and proper treatment of conflicting concurrent operations without too much lock overhead (drop table vs. insert especially) more source code documentation a little more abstraction so all csv operations are deprecated in favor of database columns where avaible last but not least, an approved way to configure the substitute logger and load it early on, which means touching the core ProcessWire class Before I invest too much into that, I'd love to hear all thoughts on this, especially if you think such a module may fit your requirements, and I would be especially happy to hear from @ryan - could you see such a mechanism in the core?
    • By workdreamer
      Hello.
      I am starting to use ProcessWire.
      So, i need to extend the ProcessTemplate Module. I need to add a required field to the templates into the Advanced Tab (for personal purposes)
      I already added the field, but inside the core folder, but this is a very bad practice.
      The best would be add the modifications inside the site folder.
      How could i extend the core module ProcessTemplate in order to not affect the core, and the processwire read my extended modifications.
       
      Thank you very much everyone.
    • By phil_s
      What are your experiences with profile/color consistency when using Image Magick for resizing?
      I know @horst is probably the person with the most experience on this, (hope you can chime in here Horst)
      Problem:
      I noticed that In some cases Image Magic resized jpgs appear darker than the original, and after some digging it appears to involve various factors concering both the image preparation (Photoshop's save for web and even general profile handling before that) and the way the Image Magic resizing process is setup.
      - Images with an embedded (srgb) profile that were exported via Photoshop's "save for web" function with "convert to srgb" and "embed profile" ON, somehow result in muted colors and a darker image, (actually it looks very much like when you would assign an srgb profile to an image that was already converted to srgb before, not dramatic, but quite noticeable with e.g. reds and cyans.)

      - I tried multiple variations, with embedded and excluded srgb profile, "convert to srgb" on and off, but the result appears to be the same darker, muted image. Need to find time to do more structured testing though..
      Possible causes:
      - The way the srgb profile is embedded in the jpg
      - The way the Imagick module detects/ignores profiles
      - Colorspace handling changes between imagick versions
      - One of the above plus these rather involved technical reccomendations (tldr: convert to linear RGB, resize, convert back)
      http://www.4p8.com/eric.brasseur/gamma.html#ImageMagick
      http://www.imagemagick.org/Usage/resize/#resize_colorspace

      Would be nice to get a discussion going here. I am out of my league with this, technical knowledge wise but I'll try to keep up
      Cheers guys,
      Phil
×
×
  • Create New...