create associative array while looping through collection in magneto 2 - php

i have a collection object
$di=array();
$products= $this->customerFactory->create()->getCollection()->addAttributeToSelect('*')->addFieldToFilter('entity_id','22');
foreach ($products as $key => $value)
{ # code... }
I want to know how to loop through this collection and create associative array ..and if result has multiple rows how to loop through it.
As final result i should get the array as
{key=>value, key1=>value1}

First of all, getCollection() already returns an array of elements of the given collection, with all its attributes (addAttributeToSelect('*')), so you are already receiving an array of objects rather than a multi-dimensional array.
In the simplest of all cases and if you need a JSON array containing all the products with all attributes, it would be as simple as this:
$jsonArray= json_encode($products); // converts all elements into a JSON representation
If you would need an associative array of elements rather than an array of objects, typecast the objects:
$assocArray= array();
foreach ($products as $product) {
$assocArray[]= (array) $product; // type-casting to array
}
If you want to iterate over each property of each product (I wouldn't know why you would want that), here's that version:
$assocArray= array();
foreach ($products as $product) {
$rowArray= array();
foreach ($product as $key => $val) {
$rowArray[$key]= $val;
}
$assocArray[]= $rowArray;
}
Hope that gives you an idea of how collections can be used in Magento work.

Related

Laravel collection find common items

I am trying to find the common items existing in a collection like the following one:
I would like to end up with a new collection that contains the 928 and the 895 (common items between the key 95 and the key 94).
How can I do it?
I have an array of keys, but I don't understand how to loop over the keys AND the values without create a mess of variables and additional arrays:
foreach ($ids as $id) {
$item_ids->each(function ($item, $key) {
});
}
Well, I ended up with that solution:
$all = $item_ids->all();
$list = [];
foreach ($all as $single) {
$list[] = $single->toArray();
}
$commonItems = collect(call_user_func_array('array_intersect', $list));
So, this is a more laravel approach:
$items = $item_ids['items']->map(function ($item){
$collection[] = $item['items'];
return collect($collection)->duplicates();
});

PHP - iterate trough arrays and set different keys

I have wrote PHP function in my Symfony project returnAllPosts() which returns all entity objects from table that are found.
I want to assign new array structure with different keys and put those values of every specific post after that and return new array result with predefined post key-value pairs.
But this specific code returns just first object not all of them? How I can get them all from foreach loop?
$posts = $this->myService->returnAllPosts();
foreach ($posts as $post) {
$post = [
'valueOne' => $post->getValueOne(),
'valueTwo' => $post->getValueTwo(),
];
$posts[] = $post;
}
return $posts;

How to get a list of unique properties from object

I have an array of objects with a 'category' property. I need to get a list of the different categories, how can I do this given that I have a method to get the category from the object? Shown below creates a list of all the categories in the array, but obviously has lots of repeated categories:
foreach (getSourceCodes() as $source) {
echo $source->getCategory();
}
You can use array_unique() in php.
$categories = array();
foreach (getSourceCodes() as $source) {
array_push($categories, $source->getCategory());
}
$categories = array_unique($categories);
If categories is multidimensional, then use this method to serialise it, then get unique array and then change it back to array.
$categories = array_map("unserialize", array_unique(array_map("serialize", $categories)));
If you use the category as an array key, it will be unique by definition.
foreach (getSourceCodes() as $source) {
// The value is irrelevant. You can use a counter if you want to keep track of that.
$an_array[$source->getCategory()] = true;
// The key is just overwritten for duplicate values of getCategory()
}
// Then you can use array_keys to get the keys as values.
var_dump(array_keys($an_array));
Not sure what format your list is in but assumed comma separated values...
$aCategories = array();
$aList = array();
foreach (getSourceCodes() as $source) {
// Get categories as comma separated string list???
$sList = $source->getCategory();
// Convert string list to array
$aTmpList = explode(",",$sList);
//Check temp list against current list for new categories
$aDiffList = array_diff($aList,$atmpList);
//Merge new categories into current list
$aList = array_merge($aDiffList,$aList);
}
// Convert array to string list
$sCategories = implode(",", $aList);

PHP, foreach doesnt return an array but array_map with same code returns an array

I want the foreach to return arrays but it just returns a single array. But the array_map with same code does.
What is the correct way of getting the arrays out of the foreach.
Why does foreach behaves differently than array_map.
Inside the file (userdata.php)
Reme:Reme1991#jourrapide.com
george bush:GeorgeBush#gmail.com
obama:obama#gmail.com
Using array_map
function registered_users(){
$file_user = file('userdata.php');
return array_map(function($user){
return explode(':',$user);
},$file_user);
} //returns the exploded array correctly.
Using foreach
function registered_users(){
$file_user = file('userdata.php');
foreach ($file_user as $user) {
return explode(':',$user);
}
}// returns Array ( [0] => Reme [1] => Reme1991#jourrapide.com )
Because array_map() iterates over all elements in the array.... the foreach() would do the same except that your return is jumping out of it on the first iteration.
function registered_users(){
$users = [];
$file_user = file('userdata.php');
foreach ($file_user as $user) {
$users[] = explode(':',$user);
}
return $users;
}
EDIT
In response to your question "Why doesn't a return from array_map terminate the iteration?"
Because array_map() is a function that loops/iterates every element in the array, executing a "callback" function against each element. Your return is in the "callback" function, which acts on one individual array element at a time, and is called multiple times by array_map(), once for each element of the array in turn.
The return in your "callback" is simply returning a modified value for that one individual element (the current element in the array_map() loop) to the array_map() function.... it's telling array_map() what the new element value should be.
The array_map() function itself can't be interrupted: it will then continue iterating over the next element, sending that in turn to the "callback" function until it has done so for every element in the array.

How to use a for loop on a collection pulled from Magento

im trying to use a for loop on products i pulled from Magento.
And it crashes when i want to use the index on a product in the loop.
$collection = Mage::getModel('catalog/product')->getCollection();
$collectionLength = count($collection);
for($j = 0; $j < $collectionLength; $j++)
{
$productFromStore = $collection[$j];//it crashes on this line of code
$sku = $productFromStore->getSku();
}
but when i use a foreach loop i can reach all the products.
foreach($collection as $product)
{
// this code works fine
$sku = $product->getSku();
}
Can someone explain what is going wrong and why?
Thanks.
First of all, You trying to iterate collection object as array
Here is Error :
Fatal error: Cannot use object of type
Mage_Catalog_Model_Resource_Product_Collection as array
, second for loop isn't the best way to iterate collections better is foreach loop becacuse for loop need to count of array emelents foreach dont need it.
Third, the best way is to use magento resource iterator.
Mage::getSingleton('core/resource_iterator')
->walk(
$query->getSelect(),
array(array($this,'callbackFunction')));
here is an example:
public function someGetCollectionMethod()
{
$products = Mage::getModel('catalog/product')->getCollection();
Mage::getSingleton('core/resource_iterator')
->walk(
$products->getSelect(),
array(array($this, 'productsCallback')));
}
public function productsCallback($args)
{
$product = Mage::getModel('catalog/product');
$prod = $product->load($args['row']['entity_id']);
Zend_Debug::dump($prod->getSku());
}
Happy coding,
Adam
Collection classes in Magento's ORM ultimately subclass Varien_Data_Collection which implements IteratorAggregate; this is why you are able to work with the collection object in an array-like fashion (i.e. foreach), but not have it work for the for loop. For one thing, dThere is no direct key-based access to the elements inside the object (_items array members) - unfortunate, given that the key for the _items array is based on the row ID.
Bottom line: working with collection items in a for loop is not very easy, not when compared to the ease of working with collection items via IteratorAggregate and all of its related goodies.
Here's an example of both. If you have an overarching need to work with the collection's items directly then you can use $collection->getItems(), but again realize that the _items array keys may not be sequential as they are based on the data. Also, note that you need to add the name attribute value to collections stored using Magento's EAV pattern:
<?php
header('Content-Type: text/plain');
include('app/Mage.php');
Mage::app();
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->addAttributeToSelect('name');
//for loop - not as much fun
for ($j=0;$j<count($collection);$j++) { //count() triggers $collection->load()
$items = $collection->getItems();
$item = current($items);
echo sprintf(
"%d:\t%s\t%s\n",
$k,
$item->getSku(),
$item->getName()
);
next($items); //advance pointer
}
//foreach - a bit better
foreach ($collection as $k => $product) {
echo sprintf(
"%d:\t%s\t%s\n",
$k,
$product->getSku(),
$product->getName()
);
}
And just in case you are wondering: Performance of FOR vs FOREACH in PHP
$array = array(
"foo" => "bar",
"bar" => "foo",
);
This type of array cannot be accessed by indexes you have to use,
$array["foo"];
If the keys are unpredictable you have to use
`foreach
I'm no expert in magento, but perhaps it's because the collection has different keys other than just numbers? Try printing out the collection with print_r to see what keys does the object have.
If you need iterations with numbers, you can always do something like that:
$i=0;
foreach($collection as $product)
{
$sku = $product->getSku();
$i++;
}
EDIT: Anyway, it seems collections aren't regular arrays, so you cannot use them the way you tried.
That's because you are sending an empty value to the getSku function.
<?php
$collection=array("book1"=>"bat","book2"=>"cat");
$collectionLength = count($collection);
for($j = 0; $j < $collectionLength; $j++)
{
$productFromStore = $collection[$j];
echo $productFromStore; //prints nothing !
}
foreach($collection as $var)
{
echo $var; //prints batcat
}
In magento collection return in form of object. use below code fetch SKU and NAME. Or use print_r($collection->getData()) to get data in array Key=>value format.
foreach($collection as $productCollection){
$sku = $productCollection->getSku();
$name = $productCollection->getName();
}

Categories