Home > Blockchain >  Foreach-loop through an array of objects, finding objects with a duplicate key-value pair and pushin
Foreach-loop through an array of objects, finding objects with a duplicate key-value pair and pushin

Time:08-25

This is a very simplified data structure of what I have; an array of std objects:

$data[] = new stdClass;
$data[0]->product_name = '1';
$data[0]->random_value = 'first';

$data[1]->product_name = '2';
$data[1]->random_value = 'second';

$data[2]->product_name = '2';
$data[2]->random_value = 'third';

$data[3]->product_name = '1';
$data[3]->random_value = 'fourth';

$data[4]->product_name = '3';
$data[4]->random_value = 'fifth';


array(5) {
  [0] => object(stdClass) {
    ["product_name"] => "1"
    ["random_value"] => "first"
  }
  [1] => object(stdClass) {
    ["product_name"] => "2"
    ["random_value"] => "second"
  }
  [2] => object(stdClass) {
    ["product_name"] => "2"
    ["random_value"] => "third"
  }
  [3] => object(stdClass) {
    ["product_name"] => "1"
    ["random_value"] => "fourth"
  }
  [4] => object(stdClass) {
    ["product_name"] => "3"
    ["random_value"] => "fifth"
  }
}

What I want to achieve is to loop through this array of objects, and for the objects that have a matching value to the key product_name, push said object(s) into a new array, unique to this key. The objects that don't have a match in the key-value pair should also be pushed into a new array, where future objects with this value to the key can be pushed into.

  • [0] and [3] both have the same value to the key product_name, so they should be put into a new array together.

  • [1] and [2] both have the same value to the key product_name, so they should be put into a new array together.

  • [4]'s value to the key product_name doesn't match any of the other objects, but should still be pushed into a new array.

I'm using a foreach-loop to iterate over the objects in the array and would like to keep it that way. Creating the new array and pushing objects into it must be done dynamically, as the database will contain new product_names in the future.

I've scratched my head at this for hours and can't seem to find a clean solution.

Here is a template for the array structure:

$data[] = new stdClass;
$data[0]->product_name = '1';
$data[0]->random_value = 'first';

$data[1]->product_name = '2';
$data[1]->random_value = 'second';

$data[2]->product_name = '2';
$data[2]->random_value = 'third';

$data[3]->product_name = '1';
$data[3]->random_value = 'fourth';

$data[4]->product_name = '3';
$data[4]->random_value = 'fifth';


foreach ($data as $data_object) {
    $data_object->product_name;
}
echo '<pre id="vardump">';
var_dump($data);
echo '</pre>';

CodePudding user response:

You can iterate over $data, pushing objects into a products array based on their product_name value. Then you can access all the products with a given name via (for example) $products[1].

$products = array();

foreach ($data as $data_object) {
    $products[$data_object->product_name][] = $data_object;
}

// product names are keys of $products
var_dump(array_keys($products));

// products for each key
var_dump($products);

Output (for your sample data):

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
array(3) {
  [1]=>
  array(2) {
    [0]=>
    object(stdClass)#1 (2) {
      ["product_name"]=>
      string(1) "1"
      ["random_value"]=>
      string(5) "first"
    }
    [1]=>
    object(stdClass)#4 (2) {
      ["product_name"]=>
      string(1) "1"
      ["random_value"]=>
      string(6) "fourth"
    }
  }
  [2]=>
  array(2) {
    [0]=>
    object(stdClass)#2 (2) {
      ["product_name"]=>
      string(1) "2"
      ["random_value"]=>
      string(6) "second"
    }
    [1]=>
    object(stdClass)#3 (2) {
      ["product_name"]=>
      string(1) "2"
      ["random_value"]=>
      string(5) "third"
    }
  }
  [3]=>
  array(1) {
    [0]=>
    object(stdClass)#5 (2) {
      ["product_name"]=>
      string(1) "3"
      ["random_value"]=>
      string(5) "fifth"
    }
  }
}

Demo on 3v4l.org

  • Related