Native function to get a special array for PHP - php

Every day , I have this pattern
- an array of objects
- i make a loop to traverse the array
foreach($arr as $obj){
$arrIds[] = $obj->Id;
$arrNames[] = $obj->Name;
}
I could build a function like arrayFromProperties($Array,$ProperyName) but I was wondering if you know a native php function to do this, or something similar, without having to write a new class/function for this.

As far as I know, you'll have to do this by your own.

Have you tried get_object_vars?

There isn't. It's not very hard to write, either. Feel free to reuse or adapt the following to your liking:
function soa_of_aos($aos)
{
$soa = array();
foreach ($aos as $i => $struct)
foreach ($struct as $field => $value)
if (!isset($soa[$field])) $soa[$field] = array($i => $value);
else $soa[$field][$i] = $value;
return $soa;
}

Related

Seeking advice to optimize the following code chunk. (I need to avoid the IF ELSES)

I have a JSON file with around 30 sub sections. Each subsection will be different. I wanted to convert the data inside it into a format i wanted. The code works fine. But i feel its not optimized 100%.
Client1Insurance, Client2Insurance, ClientFInsurance, FamilyInsurance, Client1Pension, Client2Pension, ClientFPension, FamilyPension.
Above is an example of how this JSON would look like. All above are arrays which have sub arrays inside them. There are around 30 arrays like this.
foreach ($json as $item) {
if (strpos($crmMapKey, "Insurance")) {
$returnArray[] = $this->handleInsurance($item);
} elseif (strpos($crmMapKey, "Pension")) {
$returnArray[] = $this->handlePension($item);
} ... continues the comparison till the json ends
}
I need a way to avoid this long if else comparions which I am not proud of. Will someone be able to suggest a better way to do this?
Thanks.
If they are named the same as you show in your code, something containing Insurance will call handleInsurance, etc. then just get the term and use it in the method call:
preg_match('/Insurance|Pension/', $crmMapKey, $match);
$returnArray[] = $this->{'handle'.$match[0]}($item);
If not then you can use a lookup array:
$lookup = ['Insurance' => 'doSomething', 'Pension' => 'doAnotherThing'];
preg_match('/Insurance|Pension/', $crmMapKey, $match);
$returnArray[] = $this->{'handle'.$lookup[$match[0]]}($item);
Or use the keys in the pattern so you only have to modify the array:
preg_match('/'.implode('|', array_keys($lookup)).'/', $crmMapKey, $match);
The switch I mentioned in a comment might not be the best but works:
switch(true) {
case strpos($crmMapKey, "Insurance") !== false;
$returnArray[] = $this->handleInsurance($item);
break;
case strpos($crmMapKey, "Pension") !== false;
$returnArray[] = $this->handlePension($item);
break;
//etc...
}
Another way would be to call variable based functions.
foreach ($json as $item) {
$returnArray[] = $crmMapKey($item);
}
function Client1Insurance($item) {
// Do something in here.
return $array;
}
function Client2Insurance($item) {
// Do something in here.
return $array;
}
Much more elegant way of doing things I feel.

Is this the best way to convert between two different types of array?

I need to convert array like this
array(
0=>array("key"=>"key1", "val"=>"val1"),
1=>array("key"=>"key2", "val"=>"val2"),
2=>array("key"=>"key3", "val"=>"val3"),
)
To array like this
array(
"key1"=>"val1",
"key2"=>"val2",
"key3"=>"val3",
)
I do like below:
foreach($oldArray as $element){
$newArray[$element["key"]] = $element["val"];
}
Is this the best way to convert these arrays? (Especially if the array is huge.)
The least memory consuming way would be to use generators. Something like this should work, but I haven't tested it.
function flatten(array $inArray) {
foreach($inArray as $subArray) {
yield $subArray['key'] => $subArray['val'];
}
}
$newArray = iterator_to_array(flatten($oldArray));
Note: You need PHP 5.5+ for this.
Yes, the best way is using a foreach, even if your array is huge, that's not take many time.
Is your code working now? Else I can help you.
You can tell php to use foreach on their own like below.
$array = array(
0=>array("key"=>"key1", "val"=>"val1"),
1=>array("key"=>"key2", "val"=>"val2"),
2=>array("key"=>"key3", "val"=>"val3"),
);
$result = array();
array_walk($array, function($value) use (&$result) {
$result[$value['key']] = $value['val'];
});
echo '<pre>';
print_r($result);
echo '</pre>';

Accessing an array in an object

If i knew the correct terms to search these would be easy to google this but im not sure on the terminology.
I have an API that returns a big object. There is one particular one i access via:
$bug->fields->customfield_10205[0]->name;
//result is johndoe#gmail.com
There is numerous values and i can access them by changing it from 0 to 1 and so on
But i want to loop through the array (maybe thats not the correct term) and get all the emails in there and add it to a string like this:
implode(',', $array);
//This is private code so not worried too much about escaping
Would have thought i just do something like:
echo implode(',', $bug->fields->customfield_10205->name);
Also tried
echo implode(',', $bug->fields->customfield_10205);
And
echo implode(',', $bug->fields->customfield_10205[]->name);
The output im looking for is:
'johndoe#gmail.com,marydoe#gmail.com,patdoe#gmail.com'
Where am i going wrong and i apologize in advance for the silly question, this is probably so newbie
You need an iteration, such as
# an array to store all the name attribute
$names = array();
foreach ($bug->fields->customfield_10205 as $idx=>$obj)
{
$names[] = $obj->name;
}
# then format it to whatever format your like
$str_names = implode(',', $names);
PS: You should look for attribute email instead of name, however, I just follow your code
use this code ,and loop through the array.
$arr = array();
for($i = 0; $i < count($bug->fields->customfield_10205); $i++)
{
$arr[] = $bug->fields->customfield_10205[$i]->name;
}
$arr = implode(','$arr);
This is not possible in PHP without using an additional loop and a temporary list:
$names = array();
foreach($bug->fields->customfield_10205 as $v)
{
$names[] = $v->name;
}
implode(',', $names);
You can use array_map function like this
function map($item)
{
return $item->fields->customfield_10205[0]->name;
}
implode(',', array_map("map", $bugs)); // the $bugs is the original array

AND in a PHP foreach loop?

Is it possible to have an AND in a foreach loop?
For Example,
foreach ($bookmarks_latest as $bookmark AND $tags_latest as $tags)
You can always use a loop counter to access the same index in the second array as you are accessing in the foreach loop (i hope that makes sense).
For example:-
$i = 0;
foreach($bookmarks_latest as $bookmark){
$result['bookmark'] = $bookmark;
$result['tag'] = $tags_latest[$i];
$i++;
}
That should achieve what you are trying to do, otherwise use the approach sugested by dark_charlie.
In PHP 5 >= 5.3 you can use MultipleIterator.
Short answer: no. You can always put the bookmarks and tags into one array and iterate over it.
Or you could also do this:
reset($bookmarks_latest);
reset($tags_latest);
while ((list(, $bookmark) = each($bookmarks_latest)) && (list(,$tag) = each($tags_latest)) {
// Your code here that uses $bookmark and $tag
}
EDIT:
The requested example for the one-array solution:
class BookmarkWithTag {
public var $bookmark;
public var $tag;
}
// Use the class, fill instances to the array $tagsAndBookmarks
foreach ($tagsAndBookmarks as $bookmarkWithTag) {
$tag = $bookmarkWithTag->tag;
$bookmark = $bookmarkWithTag->bookmark;
}
you can't do that.
but you can
<?php
foreach($keyval as $key => $val) {
// something with $key and $val
}
the above example works really well if you have a hash type array but if you have nested values in the array I recommend you:
or option 2
<?php
foreach ($keyval as $kv) {
list($val1, $val2, $valn) = $kv;
}
No, but there are many ways to do this, e.g:
reset($tags_latest);
foreach ($bookmarks_latest as $bookmark){
$tags = current($tags_latest); next($tags_latest);
// here you can use $bookmark and $tags
}
No. No, it is not.
You'll have to manually write out a loop that uses indexes or internal pointers to traverse both arrays at the same time.
Yes, for completeness:
foreach (array_combine($bookmarks_latest, $tags_latest) as $bookm=>$tag)
That would be the native way to get what you want. But it only works if both input arrays have the exact same length, obviously.
(Using a separate iteration key is the more common approach however.)

to print values of an array after extracting the array in php

Please help in code that i am unable to print values of associative array after extracting itself
class display{
protected $variables = array();
function set($name,$value) {
$this->variables[$name] = $value;
}
function render(){
extract($this->variables);
// ?? to print values of $variable array
}
foreach($this->variables as $key => $value) {
echo "{$key}: {$value}\n";
}
And how do you try to print the values? The array itself (it's $varables, not $variable, btw) should not be affected.
Update: For what I can tell by your reply to the other answer, you do not really need to extract array. extract jusst puts the variables into local namespace where they will be harder to enumerate. What you need is to use array as is.
foreach($this->variables as $k => $v) echo "$k: $v\n";
or whatever you want to do with them.
if you are using classes, u will need to have something like
var $variables = array(); or
public $variables = array();
and if you are using structured , you will need to do
global $variables;
inside the function .. but as u are using $this-> it indicates ur using a class. You will have to put in some more code in here to make the situation clear.

Categories