Array mapping in PHP with keys [duplicate] - php

This question already has answers here:
Generate an associative array from an array of rows using one column as keys and another column as values
(3 answers)
Closed 6 months ago.
Just for curiosity (I know it can be a single line foreach statement), is there some PHP array function (or a combination of many) that given an array like:
Array (
[0] => stdClass Object (
[id] => 12
[name] => Lorem
[email] => lorem#example.org
)
[1] => stdClass Object (
[id] => 34
[name] => Ipsum
[email] => ipsum#example.org
)
)
And, given 'id' and 'name', produces something like:
Array (
[12] => Lorem
[34] => Ipsum
)
I use this pattern a lot, and I noticed that array_map is quite useless in this scenario cause you can't specify keys for returned array.

Just use array_reduce:
$obj1 = new stdClass;
$obj1 -> id = 12;
$obj1 -> name = 'Lorem';
$obj1 -> email = 'lorem#example.org';
$obj2 = new stdClass;
$obj2 -> id = 34;
$obj2 -> name = 'Ipsum';
$obj2 -> email = 'ipsum#example.org';
$reduced = array_reduce(
// input array
array($obj1, $obj2),
// fold function
function(&$result, $item){
// at each step, push name into $item->id position
$result[$item->id] = $item->name;
return $result;
},
// initial fold container [optional]
array()
);
It's a one-liner out of comments ^^

I found I can do:
array_combine(array_map(function($o) { return $o->id; }, $objs), array_map(function($o) { return $o->name; }, $objs));
But it's ugly and requires two whole cycles on the same array.

The easiest way is to use an array_column()
$result_arr = array_column($arr, 'name', 'id');
print_r($result_arr );
Out Put
Array (
[12] => Lorem
[34] => Ipsum
)

The easiest way is to use a LINQ port like YaLinqo library*. It allows performing SQL-like queries on arrays and objects. Its toDictionary function accepts two callbacks: one returning key of the result array, and one returning value. For example:
$userNamesByIds = from($users)->toDictionary(
function ($u) { return $u->id; },
function ($u) { return $u->name; }
);
Or you can use a shorter syntax using strings, which is equivalent to the above version:
$userNamesByIds = from($users)->toDictionary('$v->id', '$v->name');
If the second argument is omitted, objects themselves will be used as values in the result array.
* developed by me

Because your array is array of object then you can call (its like a variable of class) try to call with this:
foreach ($arrays as $object) {
Echo $object->id;
Echo "<br>";
Echo $object->name;
Echo "<br>";
Echo $object->email;
Echo "<br>";
}
Then you can do
// your array of object example $arrays;
$result = array();
foreach ($arrays as $array) {
$result[$array->id] = $array->name;
}
echo "<pre>";
print_r($result);
echo "</pre>";
Sorry I'm answering on handphone. Can't edit the code

Related

array_column with an array of objects [duplicate]

This question already has answers here:
PHP. Is it possible to use array_column with an array of objects
(5 answers)
Closed 6 years ago.
TLDR; My question is different from PHP. Is it possible to use array_column with an array of objects. I want to only change the keys within the array and keep the objects, not having the objects' values stored in a separate array like the given answer.
I would like to set the keys, of an array with objects, to a value of the object. So this array:
$array = Array
(
[0] => stdClass Object
(
[id] = 12234
[value] = some value
)
[1] => stdClass Object
(
[id] = 12994
[value] = some value
)
)
Should become:
$array = Array
(
[12234] => stdClass Object
(
[id] = 12234
[value] = some value
)
[12994] => stdClass Object
(
[id] = 12994
[value] = some value
)
)
Now I could loop over the array, but I would prefer a more cleaner solution. I thought this should work:
$newArray = array_column($array, null, 'id');
The only problem is I'm having an array of objects instead of an array of arrays and I'm not using PHP7 yet. Now I found a similar question over here
PHP. Is it possible to use array_column with an array of objects
But the thing is it doesn't return what I expected. Cause this:
$newArray = array_map(function($o) {
return is_object($o) ? $o->id : $o['id'];
}, $array);
Returns
Array
(
[0] => 12234
[1] => 12994
)
Anyone who knows a clean solution (so without a for or foreach loop) for this?
$array = array_combine(array_map(function ($o) { return $o->id; }, $array), $array);
Whether this is really a lot better than a simple foreach loop, aside from "but, but, functional programming...!", is debatable.
// your data
$array = array(
(object) array(
"id" => "12234",
"value" => "some value",
),
(object) array(
"id" => "12235",
"value" => "some value",
),
(object) array(
"id" => "12236",
"value" => "some value",
),
);
// let's see what we have
print_r($array);
// here comes the magic ;-)
function key_flip_array($array, $keyname){
$keys = array_map(function($item, $keyname){
return (is_object($item) && isset($item->{$keyname}) ? $item->{$keyname} : (is_array($item) && isset($item[$keyname]) ? $item[$keyname] : null));
}, $array, array_fill(0, count($array), $keyname));
return array_combine($keys, $array);
}
$array = key_flip_array($array, "id");
// i hope this is what you wish to see
print_r($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.

wordpress $wpdb select results to an array

$wp->get_results will return an array and formats the array depends if the second parameter is specified; if not, it is default to an object, right? But my question is it possible to retrieve results then store it the an array? Like this $arr = array(1,2,3,4,5)? What my main concern is this.. I want to search in the array if the value is present.
Now I can't do a in_array if the returned results is like this.
$arr = array(array('1'), array('2'), array('3'), array('4'), array('5'));
Any help would be much appreciated. Thanks.
EDITED
my $arr would look like this
Array ( [0] => stdClass Object ( [code] => 8 [id] => ) [1] => stdClass Object ( [code] => 1 [id] => ) )
EDITED
Found a solution:
if (in_array(array('1'), $arr) {
// found value
}
You can not match directly, for matching, it you will have to do something like this :
$arr = array(array('1'), array('2'), array('3'), array('4'), array('5'));
foreach($arr as $newar)
{
if (in_array('2',$newar))
{
echo 'hello';
}
}
I'm not really following the problem here, but assuming you want to find a specific value inside the wpdb results......
foreach($arr as $key => $row) {
if($row->code == $VALUE_YOU_WANT_TO_MATCH) {
// do something
break;
}
}
Note: $arr is an array of objects, its not a multidimensional array.
say for example I want to check if if code = 1 exist in my result.
foreach($arr as $myarr){
if ($myarr->code == "1"){
echo "record was found\n";
break;//this line makes the foreach loop end after first success.
}
}

stdClass to array?

i have:
stdClass Object
(
[0] => stdClass Object
(
[one] => aaa
[two] => sss
)
[1] => stdClass Object
(
[one] => ddd
[two] => fff
)
[2] => stdClass Object
(
[one] => ggg
[two] => hhh
)
}
and i must get this with keys, for example:
$var = $stdClass[0];
but i have error:
Fatal error: Cannot use object of type stdClass as array in
Is possible parse this stdClass to array and use this with keys?
Cast it to an array:
$array = (array)$stdClass;
If you're using json_decode to convert that JSON string into an object, you can use the second parameter json_decode($string, true) and that will convert the object to an associative array.
If not, what everybody else has said and just type cast it
$array = (array) $stdClass;
Your problem is probably solved since asking, but for reference, quick uncle-google answer:
function objectToArray($d) {
if(is_object($d)) {
$d = get_object_vars($d);
}
if(is_array($d)) {
return array_map(__FUNCTION__, $d); // recursive
} else {
return $d;
}
}
Full article here. Note I'm not associated with the original author in any way.
Cast it
$array = (array) $stdObject;
Of course you can typecast, $var = (array) $obj;, but I would suggest ArrayAccess to your class.
By using ArrayAccess, you can then treat your objects and data as if it was an array, or natively as an object.
Cast it into an array. Currently it is not readable to PHP as an array.
$array = (array)$stdClass;
Essentially, just type cast it:
$arr = (array)$obj;
$var = $arr[0];
But read the caveats here.
If you have an nested array you can used json_encode and json_decode to convert the whole object to an array:
$result = json_decode(json_encode($source), JSON_OBJECT_AS_ARRAY);
This one worked for me,
The decoding and encoding makes for a regular array
$array = json_decode(json_encode($object), True);
function load_something () : \stdClass {
$result = new \stdClass();
$result->varA = 'this is the value of varA';
$result->varB = 'this is the value of varB';
$result->varC = 'this is the value of varC';
return $result;
}
$result = load_something();
echo ($result instanceof stdClass)?'Object is stdClass':'Object is not stdClass';
echo PHP_EOL;
print_r($result);
//directly extract a variable from stdClass
echo PHP_EOL . 'varA = ' . ($result->varA);
//convert to array, then extract
$array = (array)$result;
echo PHP_EOL . 'varA = ' . $array['varA'];
stdClass is an object so u can access value from it like
echo stdClass->one;

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