Select only unique array values from this array - php

I have the following variable $rows:
Array (
[0] => stdClass Object
(
[product_sku] => PCH20
)
[1] => stdClass Object
(
[product_sku] => PCH20
)
[2] => stdClass Object
(
[product_sku] => PCH19
)
[3] => stdClass Object
(
[product_sku] => PCH19
)
)
I need to create second array $second containing only unique values:
Array (
[0] => stdClass Object
(
[product_sku] => PCH20
)
[1] => stdClass Object
(
[product_sku] => PCH19
)
)
But when i run array_unique on $rows, i receive:
Catchable fatal error: Object of class stdClass could not be
converted to string on line 191

array_unique()
The optional second parameter sort_flags may be used to modify the sorting behavior using these values:
Sorting type flags:
SORT_REGULAR - compare items normally (don't change types)
SORT_NUMERIC - compare items numerically
SORT_STRING - compare items as strings
SORT_LOCALE_STRING - compare items as strings, based on the current locale.
Also note the changenotes below
5.2.10 Changed the default value of sort_flags back to SORT_STRING.
5.2.9 Added the optional sort_flags defaulting to SORT_REGULAR. Prior to 5.2.9, this function used to sort the array with SORT_STRING internally.
$values = array_unique($values, SORT_REGULAR);

$uniques = array();
foreach ($array as $obj) {
$uniques[$obj->product_sku] = $obj;
}
var_dump($uniques);

The default behavior of function array_unique() is to treat the values inside as strings first. So what's happening is that PHP is attempting to turn your objects into strings (which is throwing the error).
You can modify your function call like this:
$uniqueArray = array_unique($rows, SORT_REGULAR);
This will compare values without changing their data type.

Please check below code, I hope this will be helpful to you.
$resultArray = uniqueAssocArray($actualArray, 'product_sku');
function uniqueAssocArray($array, $uniqueKey)
{
if (!is_array($array))
{
return array();
}
$uniqueKeys = array();
foreach ($array as $key => $item)
{
$groupBy=$item[$uniqueKey];
if (isset( $uniqueKeys[$groupBy]))
{
//compare $item with $uniqueKeys[$groupBy] and decide if you
//want to use the new item
$replace= false;
}
else
{
$replace=true;
}
if ($replace)
$uniqueKeys[$groupBy] = $item;
}
return $uniqueKeys;
}

Related

PHP - Sort associative array based on predifined order of keys

I have the following structure:
Array
(
[Lhgee] => some object
[V4ooa] => some object
[N0la] => some object
)
I need to sort this array in to this order: V4ooa, Lhgee, N0la
so after sorting the array would like this:
Array
(
[V4ooa] => some object
[Lhgee] => some object
[N0la] => some object
)
I've looked at uasort and I'm pretty sure it's what I need (as I need to keep all the data against the relevant array) but can't work out how to acheive this with associative arrays as all the examples seem to use integer indexes.
Thanks
i think you need to check this
$order = array('V4ooa', 'Lhgee', 'N0la');
$array = array
(
['Lhgee'] => some object
['V4ooa'] => some object
['N0la'] => some object
);
$orderedArray = sortArray($array, $order);
var_dump($orderedArray);
function sortArray(array $array, array $order) {
$ordered = array();
foreach($order as $key) {
if(array_key_exists($key,$array)) {
$ordered[$key] = $array[$key];
unset($array[$key]);
}
}
return $ordered;
}
UPDATE
Check this
and
This

PHP Array: array filter with argument

I have this simple array in PHP that I need to filter based on an array of tags matching those in the array.
Array
(
[0] => stdClass Object
(
[name] => Introduction
[id] => 798162f0-d779-46b6-96cb-ede246bf4f3f
[tags] => Array
(
[0] => client corp
[1] => version 2
)
)
[1] => stdClass Object
(
[name] => Chapter one
[id] => 761e1909-34b3-4733-aab6-ebef26d3fcb9
[tags] => Array
(
[0] => pro feature
)
)
)
When supplied with 'client corp', the output should be the above array with only the first item.
So far I have this:
$selectedTree = array_filter($tree,"checkForTags");
function checkForTags($var){
$arr = $var->tags;
$test = in_array("client corp", $arr, true);
return ($test);
}
However, the result is that it's not filtering. When I echo $test, I get 1 all the time. What am I doing wrong?
Something like this should do the trick:
$selectedTree = array_filter(array_map("checkForTags", $tree ,array_fill(0, count($tree), 'client corp')));
function checkForTags($var, $exclude){
$arr = $var->tags;
$test = in_array($exclude, $arr, true);
return ($test ? $var : false);
}
array_map() makes sure you can pass arguments to the array. It returns each value altered. So in the returning array, some values are present, others are set to false. array_filter() with no callback filters all falsey values from that array and you are left with the desired result
The in_array() function returns TRUE if needle is found in the array and FALSE otherwise. So by getting 1 as a result that means that "client corp" is found.
Check PHP in_array() manual
You can user array_search() to return the array key instead of using in_array().

replace duplicate fom stdclass array php [duplicate]

This question already has answers here:
How can I remove duplicates in an object array in PHP?
(2 answers)
Closed 8 years ago.
When I print $online_performers variable I want to get a unique value for id 2. Do I need to convert them in standard array first or is that possible without it? (remove all duplicates).Please check my new code for this.
Array
(
[0] => stdClass Object
(
[id] => 1
[username] => Sample1
)
[1] => stdClass Object
(
[id] => 2
[username] => Sample1
)
[2] => stdClass Object
(
[id] => 2
[username] => Sample1
)
[3] => stdClass Object
(
[id] => 4
[username] => Sample4
)
)
to
Array
(
[0] => stdClass Object
(
[id] => 1
[username] => Sample1
)
[1] => stdClass Object
(
[id] => 4
[username] => Sample4
)
)
PHP has a function called array_filter() for that purpose:
$filtered = array_filter($array, function($item) {
static $counts = array();
if(isset($counts[$item->id])) {
return false;
}
$counts[$item->id] = true;
return true;
});
Note the usage of the static keyword. If used inside a function, it means that a variable will get initialized just once when the function is called for the first time. This gives the possibility to preserve the lookup table $counts across multiple function calls.
In comments you told, that you also search for a way to remove all items with id X if X appears more than once. You could use the following algorithm, which is using a lookup table $ids to detect elements which's id occur more than ones and removes them (all):
$array = array("put your stdClass objects here");
$ids = array();
$result = array();
foreach($array as $item) {
if(!isset($ids[$item->id])) {
$result[$item->id]= $item;
$ids[$item->id] = true;
} else {
if(isset($result[$item->id])) {
unset($result[$item->id]);
}
}
}
$result = array_values($result);
var_dump($result);
If you don't care about changing your keys you could do this with a simple loop:
$aUniq = array ();
foreach($array as $obj) {
$aUniq[$obj->id] = $obj;
}
print_r($aUniq);
Let's say we have:
$array = [
//items 1,2,3 are same
(object)['id'=>1, 'username'=>'foo'],
(object)['id'=>2, 'username'=>'bar'],
(object)['id'=>2, 'username'=>'baz'],
(object)['id'=>2, 'username'=>'bar']
];
Then duplication depends of what do you mean. For instance, if that's about: two items with same id are treated as duplicates, then:
$field = 'id';
$result = array_values(
array_reduce($array, function($c, $x) use ($field)
{
$c[$x->$field] = $x;
return $c;
}, [])
);
However, if that's about all fields, which should match, then it's a different thing:
$array = [
//1 and 3 are same, 2 and 3 are not:
(object)['id'=>1, 'username'=>'foo'],
(object)['id'=>2, 'username'=>'bar'],
(object)['id'=>2, 'username'=>'baz'],
(object)['id'=>2, 'username'=>'bar']
];
You'll need to identify somehow your value row. Easiest way is to do serialize()
$result = array_values(
array_reduce($array, function($c, $x)
{
$c[serialize($x)] = $x;
return $c;
}, [])
);
But that may be slow since you'll serialize entire object structure (so you'll not see performance impact on small objects, but for complex structures and large amount of them it's sounds badly)
Also, if you don't care about keys in resulting array, you may omit array_values() call, since it serves only purpose of making keys numeric consecutive.

Convert array of MongoId objects to an array of strings

[a] => Array (
[0] => MongoId Object (
[$id] => 506479dc9a5be1596b1bd97d
),
[1] => MongoId Object (
[$id] => 506479dc9a5be1596b1bd97d
)
)
I have an array like this one. I need to change the values to string, to change it to something like this:
array (
0 => "506479dc9a5be1596b1bd97d",
1 => "506479dc9a5be1596b1bd97d",
)
This is my solution, but it is expensive and I will be using this in a for loop.
$yut = implode(",", $a);
$arr = explode(",", $yut);
Are there any other solution?
You can just use array_map to call MongoId::__toString() which would convert all Mongo Object in your array to string
$list = array_map(function($var){ return $var->__toString(); }, $yourArray);
$new_array = array_map('strval', $array);
strval is php built in function that returns string value
like
function ($value){
return (string)$value;
}

Converting array and objects in array to pure array [duplicate]

This question already has answers here:
Convert a PHP object to an associative array
(33 answers)
Closed 1 year ago.
My array is like:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => demo1
)
[1] => stdClass Object
(
[id] => 2
[name] => demo2
)
[2] => stdClass Object
(
[id] => 6
[name] => otherdemo
)
)
How can I convert the whole array (including objects) to a pure multi-dimensional array?
Have you tried typecasting?
$array = (array) $object;
There is another trick actually
$json = json_encode($object);
$array = json_decode($json, true);
You can have more info here json_decode in the PHP manual, the second parameter is called assoc:
assoc
When TRUE, returned objects will be converted into associative arrays.
Which is exactly what you're looking for.
You may want to try this, too : Convert Object To Array With PHP (phpro.org)
Just use this :
json_decode(json_encode($yourArray), true);
You can use array_walk to convert every item from object to array:
function convert(&$item , $key)
{
$item = (array) $item ;
}
array_walk($array, 'convert');
Assuming you want to get to this pure array format:
Array
(
[1] => "demo1",
[2] => "demo2",
[6] => "otherdemo",
)
Then I would do:
$result = array();
foreach ($array as $object)
{
$result[$object->id] = $object->name
}
(edit) Actually that's what I was looking for possibly not what the OP was looking for. May be useful to other searchers.
You should cast all objets, something like :
$result = array();
foreach ($array as $object)
{
$result[] = (array) $object
}
As you are using OOP, the simplest method would be to pull the code to convert itself into an array to the class itself, you then simply call this method and have the returned array populate your original array.
class MyObject {
private $myVar;
private $myInt;
public function getVarsAsArray() {
// Return the objects variables in any structure you need
return array($this->myVar,$this->myInt);
}
public function getAnonVars() {
// If you don't know the variables
return get_object_vars($this);
}
}
See: http://www.php.net/manual/en/function.get-object-vars.php for info on get_object_vars()
it you have object and you want to set a value as array
use
$this->object->pluck('name');
then you get the value as array of names like
["name1", "name2", "name3"];

Categories