DEV Community

Cover image for PHP Array Reduce function
Matus Stafura
Matus Stafura

Posted on

PHP Array Reduce function

Table of Contents

About Array Reduce

array_reduce is an array function that iteratively reduces an array to a single value by applying a callback function to elements in the array.

array_reduce(
  array $array, 
  callable $callback, 
  mixed $initial = null
): mixed
Enter fullscreen mode Exit fullscreen mode

It takes the following parameters:

  • an array (what do we want to reduce),
  • callback (the logic),
  • initial value(for example, an empty array []).

Simple example:

Let's find unique values in array.

1. We have an array of products

// an array
$products = [
  "shirt",
  "shoes",
  "shirt"
];
Enter fullscreen mode Exit fullscreen mode

2. A callback function, which checks if an item is already in an array.

$reducer = function ($all, $item) {
  if (!in_array($item, $all)) {
    array_push($all, $item);
  }
  return $all;
};
Enter fullscreen mode Exit fullscreen mode
  • The variable $item holds the value of the current iteration of $products.
  • The variable $all holds the return value of the previous iteration. Its initial value is defined as the last parameter in array_reduce.

3. initial value

Since we return an array in the callback, the type must match the initial array (we define an empty array as the initial value).

$initial = [];
Enter fullscreen mode Exit fullscreen mode

array_reduce()

$products = [
  "shirt",
  "shoes",
  "shirt"
];

$reducer = function ($all, $item) {
  if (!in_array($item, $all)) {
    array_push($all, $item);
  }
  return $all;
};

$initial = [];

array_reduce($products, $reducer, $initial);

// this will return
// [
//   "shirt",
//   "shoes",
// ]
Enter fullscreen mode Exit fullscreen mode
if we pass some initial values
array_reduce($products, $reducer, ["hat"]);

// this will return
// [
//   "hat",
//   "shirt",
//   "shoes",
// ]
Enter fullscreen mode Exit fullscreen mode
also, everything in one place:
array_reduce(
  ["shirt", "shoes", "shirt"],    // an array to reduce
  function ($all, $item) {        // callback
    if (!in_array($item, $all)) {
      array_push($all, $item);
    }
    return $all;
  },
  []                              // initial
);
Enter fullscreen mode Exit fullscreen mode

Obviously, we can use array_unique($products) instead to achieve the same results in this example.

Practical example:

Let's say we have an array of products(key, value structure).

$products = [
  ["name" => "Product 1", "price" => 10],
  ["name" => "Product 1", "price" => 10],
  ["name" => "Product 1", "price" => 10],
  ["name" => "Product 2", "price" => 2],
  ["name" => "Product 3", "price" => 7],
  ["name" => "Product 2", "price" => 2],
];
Enter fullscreen mode Exit fullscreen mode

And we need to create an array where we count the same products ($quantity) and sum their price ($total) like this:

[
  "Product 1" => [
    "total" => ...,
    "quantity" => ...,
  ],
  "Product 2" => [
    "total" => ...,
    "quantity" => ...,
  ],
  ...
]
Enter fullscreen mode Exit fullscreen mode

we can use an array_reduce function:

array_reduce($products, $reducer, []);
Enter fullscreen mode Exit fullscreen mode

where we pass $products and an empty array as initial value. all we need is to write the callback.

then, in the callback:

  1. since $item is a key-value pair (["name" => "Product 1", "price" => 10]) for simplicity, we assign the name and its price to variables.

  2. We check if the item is in the array ($all):

  • if there is one with the same key, we increase its quantity by 1 and add the price.
  • if not, we push the item to $all and set its quantity to 1.
$products = [
  ["name" => "Product 1", "price" => 10],
  ["name" => "Product 1", "price" => 10],
  ["name" => "Product 1", "price" => 10],
  ["name" => "Product 2", "price" => 2],
  ["name" => "Product 3", "price" => 7],
  ["name" => "Product 2", "price" => 2],
];

$reducer = function ($all, $item) {
  $name = $item["name"];
  $price = $item["price"];
  if (isset($all[$name])) {
    $all[$name]["quantity"]++;
    $all[$name]["total"] += $price;
  } else {
    $all[$name]["total"] = $price;
    $all[$name]["quantity"] = 1;
  }
  return $all;
};

array_reduce($products, $reducer, []);

// and that will return:
// [
//   "Product 1" => [
//     "total" => 30,
//     "quantity" => 3,
//   ],
//   "Product 2" => [
//     "total" => 4,
//     "quantity" => 2,
//   ],
//   "Product 3" => [
//     "total" => 7,
//     "quantity" => 1,
//   ],
// ]
Enter fullscreen mode Exit fullscreen mode

Try the code:

https://replit.com/@stafura/arrayreduce-in-PHP#main.php

Use cases:

There are many ways you can use the array_reduce function, such as:

  • summing up all the elements of an array,
  • flattening a nested array,
  • grouping elements based on some criterion,
  • counting the occurrences of items in an array,
  • filtering an array based on some condition.

more info:
https://www.php.net/manual/en/function.array-reduce.php

Top comments (0)