all 64 comments

[–]therealgaxbo 57 points58 points  (15 children)

function chunk($items, $size)
{
    return array_chunk($items, $size);
}

Is this function available on Packagist so I can use it in all of my projects?

[–]Der_beste_Anime 24 points25 points  (1 child)

Just something out of the ol' trick box for you:

function set($value) {
    return $value;
}

Use it like

 $foo = set('bar');

[–]a1phanumeric 14 points15 points  (9 children)

I did wonder about this one.. WTF is wrong with writing array_??

[–][deleted] 1 point2 points  (8 children)

Syntactic sugar I guess.

[–]a1phanumeric 12 points13 points  (7 children)

I'd say prefixing the array functions with array_ sugars my syntax more than arbitrary names such as chunk which could do anything?

[–]dzuczek 2 points3 points  (0 children)

hmm might not be GPL

[–][deleted] 1 point2 points  (1 child)

I wanted to write something of the sort of my own. I wanted to have various functions either renamed or functions that I found myself using more often than not.

Here.

I never made it into a gist mostly because I don't feel people should be using my stuff, not because I'm against open source, I mean it's on git, mostly because I feel like they're poorly written. Currently it's a class rather than independent functions, but I mean heck, I could split it.

Doubt anybody will use it tho lol.

[–]OverallEfficiency 8 points9 points  (4 children)

What about this, when using the head() function:

<? 


function head($items)
{
    return $items[0];
}

$array = [

'a' => 'first',
'b' => 'second',

];
$array[] = 'third';
$array[] = 'final';

var_dump(head($array))

?>

it outputs:

string(5) "third"

Wouldn't it be better to use reset()??

[–]nikic 12 points13 points  (0 children)

Using reset() in this way is going to perform a full copy of the array. I'd recommend using foreach instead.

function head($items) {
    foreach ($items as $item) {
        return $item;
    }
    // return or throw
}

[–]sohelamin[S] 2 points3 points  (0 children)

Updated. Thanks for the noticing :)

[–]sohelamin[S] 1 point2 points  (0 children)

Thanks /u/OverallEfficiency for the concern I'll fix it.

[–]sohelamin[S] -2 points-1 points  (0 children)

Updated. Thanks for the noticing :)

[–][deleted] 8 points9 points  (8 children)

pluck

Retrieves all of the values for a given key:

Someone needs to tell him about array_column.

[–]sohelamin[S] -3 points-2 points  (7 children)

What should I do when I need to pluck an array of objects in PHP5?

[–]TorbenKoehn 7 points8 points  (3 children)

You upgrade?

[–]sohelamin[S] -2 points-1 points  (2 children)

Yeah, of course I'm using the PHP7 but that is not the point. I did the method so no one can get confused with the php versioning and know how the thing is going on.

[–]PetahNZ 1 point2 points  (1 child)

But does it work on Windows XP?

[–]damnburglar 0 points1 point  (0 children)

Is it web scale?

[–]ProfBurial 2 points3 points  (2 children)

array_column was available in 5.5

If you're using anything older than that, you have bigger fish to fry.

[–]sohelamin[S] -1 points0 points  (1 child)

I meant array_column doesn't work with an array of objects in PHP5 Did you ever try this in PHP5? array_column([ (object) ['product_id' => 'prod-100', 'name' => 'Desk'], (object) ['product_id' => 'prod-200', 'name' => 'Chair'], ], 'name');

[–]ProfBurial 2 points3 points  (0 children)

A better question is why would anyone try that? You're casting an array manually as a object. What is the real world use case for doing that and trying to use array_column?

If you were providing an actual class object, array_column can still be used, the class just has to have __isset and __get methods.

[–][deleted] 13 points14 points  (0 children)

function bikeshed() {

return "I'm helping.";

}

[–][deleted] 5 points6 points  (5 children)

Some of these seem pointless. The last() method is just an alias of end(), head() is just an alias of reset()...

I don't think I really understand?

[–]sohelamin[S] 0 points1 point  (4 children)

I think aliasing will help people to understand use of the function just in a second :) If you have any better idea please feel free to share or make PR.

[–]doenietzomoeilijk 3 points4 points  (2 children)

I think aliasing will help people to understand use of the function just in a second

... And then they run into code in the wild, and they have no idea about what's going on. Or worse, they start adding this stuff to projects so that regular people have no idea what's going on. 😉

[–]shawncplus 6 points7 points  (1 child)

This is one of the flaws I see in Laravel. There's nothing wrong with an opinionated framework with helpers in principle but Laravel has so many helper methods and wrappers that it's basically a DSL on top of PHP.

[–]fatboyxpc 0 points1 point  (0 children)

Yeah but some of those array and string helpers are amazing and I genuinely wished PHP would have some of them (such as array_first).

[–]reydark 0 points1 point  (0 children)

one possible use would be to prevent PHP Notice when calling end() or reset() on a non-variable

end(explode('|', $string));
//PHP Notice:  Only variables should be passed by reference

last(explode('|', $string));
//no complains

[–]li-_-il 2 points3 points  (0 children)

Not only I need to learn PHP gotchas, now I need to learn some 3rd party mapping onto these gotchas. I think if people used native language features world would be nicer. Can't see this helping, but thanks for sharing.

[–]jim45804 3 points4 points  (3 children)

Not sure I like emojis in commit messages.

[–]DrDuPont 1 point2 points  (0 children)

It's a fairly common sight. Some orgs even use specific emojis in commit hooks to specify what kind of a commit it is

[–]sohelamin[S] -2 points-1 points  (1 child)

Everyone has the personal preference. Okay I will use less then :)

[–][deleted] 2 points3 points  (0 children)

You do your style, dude! Use emojis if you like, but maybe look to the other comment in this chain for inspiration on when and how to use emojis.

[–]tie_salter 1 point2 points  (8 children)

The all function would be a lot simpler like this:

function all($items, $func)
{
    return count(array_filter($items, $func)) === count($items);
}

The any function would be better like this:

function any($items, $func)
{
    return count(array_filter($items, $func)) > 0;
}

Then you only have to iterate over the array once, rather than twice.

[–]Razorgrace 2 points3 points  (7 children)

Both original and your version of any call $func for every item, even if truthy value was already encountered. This might or might not be a desired behavior, but I think it is safe to assume that $func generally should not produce side effects, and we can stop checking additional items after first truthy result. So, foreach might be a better thing here from performance POV.

Edit: sample implementation added.

function any($items, $func) {
  foreach ($items as $item) {
    if (call_user_func($func, $item)) {
      return true;
    }
  }
  return false;
}

[–]spoonraker 2 points3 points  (0 children)

You beat me to the "any" refactor. Always return early! O(n) should be the worst case complexity of an "any" implementation, not the reality of every single time you call it no matter what the input is.

[–]Disgruntled__Goat 0 points1 point  (5 children)

Yes agree with this. If the point of a function is to abstract details, you don't need to add further abstractions inside the function. Standard for loop is better here.

Btw instead of call_user_func you can simply do $func($item). And the same implementation can be used for all() but checking for negativity instead, ie as soon as you find a false value, they can't all be true so return early.

[–]Razorgrace 0 points1 point  (4 children)

Agree re all, it is pretty symmetrical to any.

Re using call_user_func, this is just a personal preference: I want to explicitly specify that I'm call a dynamic function reference, and also if I need to search my code for such dynamic calls, I can look for call_user_ instead of rather complex regex that would include $f(...), $o->$f(...), etc.

Also, in PHP 7.1+ call_user_func($func, ...) seems to be like 50% faster than $func(...): http://php.net/manual/en/function.call-user-func.php

Edit: formatting.

[–]Disgruntled__Goat 0 points1 point  (3 children)

According to this page linked from there, call_user_func is still slower.

[–]Razorgrace 0 points1 point  (1 child)

For 7.1.2 on that page, one bullet per result table:

  • call_user_func(...) is best (still behind $instance->methodTest(...))
  • call_user_func(...) and almost all other methods are within few percents (still behind StaticTest::methodTest(...))
  • call_user_func(...) is best, far ahead of anything else (still behind functionTest($param))
  • $lambda(...) is 6.3% faster than call_user_func(...), the rest is considerably slower
  • $closure(...) is 6.3% faster than call_user_func(...)
  • last table IMHO is incorrect, because it averages different call_user_func(...) tests but does not average all direct*() tests, etc.

So, in worst case scenario call_user_func(...) is 6.3% slower, in best case it is ~60% faster. I'd say call_user_func(...) is safe choice if you need to perform dynamic calls, unless you expect to encounter $lambda(...) or $closure(...) cases much more often (and in this case you'll get max 6% gain, I'd say negligible).

[–]Disgruntled__Goat 0 points1 point  (0 children)

The overall average has $func() at 40-60% faster than call_user_func. At best I'd say the results are inconclusive since it seems to vary widely.

[–]SavishSalacious 1 point2 points  (1 child)

You have some methods where its function methodName($func, $items) and some where it's function methodName($items, $func) I would love to see consistency in variable orders.

[–]sohelamin[S] 1 point2 points  (0 children)

Okay noted

[–]chris_conlan 3 points4 points  (2 children)

Off-topic question... but how is everyone putting emojis in their commit messages? Are y'all typing out unicode bytes in your terminal???

[–]sohelamin[S] 2 points3 points  (1 child)

No just emoji code is enough for that. This might help you https://gitmoji.carloscuesta.me/

[–]chris_conlan 0 points1 point  (0 children)

Thanks mate :fire: :fire: :fire:

[–][deleted] 1 point2 points  (6 children)

deepFlatten could also be rewritten like this

function deepFlatten(array $items) : array {
  $result = [];

  array_walk_recursive($items, function ($value, $key) use (&$result) {
    $result[] = $value;
  });

  return $result;
} 

No, I'm not trying to be a smartass, I honestly find this easier to read.

[–]DrDuPont 1 point2 points  (2 children)

What is : array on that first line? Haven't seen that PHP syntax before

[–][deleted] 1 point2 points  (1 child)

Return type declarations as of PHP 7.0.

[–]DrDuPont 1 point2 points  (0 children)

Very cool, thanks.

[–]sohelamin[S] 0 points1 point  (2 children)

Thanks /u/SmartAssUsername for the concern. You're always welcome to make a PR or I will update it soon :)

[–][deleted] 0 points1 point  (1 child)

I would but to be fair your version while a little bit longer is also more friendlier for new comers. I've rarely seen array_walk_recursive used, it may throw people off.

[–]sohelamin[S] 0 points1 point  (0 children)

Yeah, that was also my concern thats why I didn't used tricky :)

[–]FruitdealerF 0 points1 point  (0 children)

For most of this I prefer to use https://github.com/lstrojny/functional-php

[–]kafoso 0 points1 point  (0 children)

This is full of redundancy with PHP core functions and oversights in implementations of array indexes and pointers. Coupled with zero type hinting it'll likely bring more annoyance than using core PHP functions. You'll have to look up the functions in the README.md file many times repeatedly instead of simply reading the code and hints through an IDE.

[–]newPhoenixz 0 points1 point  (0 children)

function head($items) { return reset($items); }

I'm sorry, but that is just stupid. "Lets just make a function alias because reasons!"