get an array element where another element is known? - php

Array
(
[0] => Array
(
[what] => b4
[map] => 74,76,77,83
)
[1] => Array
(
[what] => b2
[map] => 53,82
)
[2] => Array
(
[what] => b1
[map] => 36
)
)
abc('b4');
function abc($what){
$map = // element `map` where `what` = $what;
}
So I need to get map where what is equal to $what;
For example - if $what is b4 result should be 74,76,77,83; and so on.
How can I do this?

If you are going to access the data on a regular basis and the what is unique, then use array_column() with the third parameter as the column to use as the key. Then your array is easily access with what and no loops are harmed in this answer...
$array = Array
(
Array
(
"what" => "b4",
"map" => "74,76,77,83"
),
Array
(
"what" => "b2",
"map" => "53,82"
),
Array
(
"what" => "b1",
"map" => "36"
)
);
$array = array_column($array, null, "what");
echo $array['b4']['map'];
gives...
74,76,77,83

With array_search() and array_column() you can get the matching $map in one line:
<?php
$array = Array
(
Array
(
"what" => "b4",
"map" => "74,76,77,83"
),
Array
(
"what" => "b2",
"map" => "53,82"
),
Array
(
"what" => "b1",
"map" => "36"
)
);
function abc($array, $what) {
return $array[array_search($what, array_column($array, 'what'))]['map'];
}
echo abc($array, "b4");
The function de-constructed and explained:
function abc($array /* the complete input array */, $what /* the search string */) {
// get the key of the sub-array that has $what in column 'what':
$key = array_search($what, array_column($array, 'what'));
// use that key to get 'map' on index $key
return $array[$key]['map'];
}
A working fiddle can be found here: https://3v4l.org/0NpcX

I think "walking" through an array is easy to read and understand:
<?php
$map = [
[
'what' => "b4",
'map' => "74,76,77,83"
],
[
'what' => "b2",
'map' => "53,82"
],
[
'what' => "b1",
'map' => "36"
]
];
function lookupWhatInMap(&$map, $what) {
array_walk($map, function($entry, $key) use ($what) {
if ($entry['what'] == $what) {
print_r($entry['map']);
}
});
}
lookupWhatInMap($map, "b4");

All you have to do is loop through your map and compare values.
function abc($what){
$map = [...];
foreach($map as $item) {
if (isset($item[$what]) ) {
return $item["map"];
}
}
return false;
}

If you just want 1 value from the array, you could use a foreach and a return statement where there is a match:
$a = [
[
"what" => "b4",
"map" => "74,76,77,83"
],
[
"what" => "b2",
"map" => "53,82"
],
[
"what" => "b1",
"map" => "36"
]
];
function abc($what, $arrays)
{
foreach ($arrays as $array) {
if ($array['what'] === $what) {
return $array['map'];
}
}
return false;
}
echo(abc('b4', $a)); // 74,76,77,83
Demo

https://ideone.com/V9WNNx
$arr[] = [
'what' => 'b4',
'map' => '74,76,77,83'
];
$arr[] = [
'what' => 'b2',
'map' => '53,82'
];
$arr[] = [
'what' => 'b1',
'map' => '36'
];
echo abc('b4', $arr);
function abc($what, $arr){
$map = null;
$idx = array_search($what, array_column($arr, 'what'));
if ($idx !== false) {
$map = $arr[$idx]['map'];
}
return $map;
}

Related

PHP Loop through multi-dimensional array into new array

I have a PHP array like this...
[level1] => Array
(
[random475item] => Array
(
[attr1] => tester1
[attr2] => tester2
[attr3] => tester3
)
[random455item] => Array
(
[attr1] => tester1
[attr2] => tester2
[attr3] => tester3
)
)
I am trying to get the values of the attr2 fields in a new array. I can specify a specific like this...
$newarray = array();
newarray [] = $array['level1']['random475item']['attr2'];
newarray [] = $array['level1']['random455item']['attr2'];
But is there a way to automate this as it could be 50 random items coming up and I don't want to have to keep adding them manually.
https://www.php.net/manual/en/function.array-column.php and the code below at
https://3v4l.org/8j3ae
<?php
$array = ['level1' => [
'item1' => [
'attr1' => 'test1',
'attr2' => 'test2',
'attr3' => 'test3'
],
'item2' => [
'attr1' => 'test4',
'attr2' => 'test5',
'attr3' => 'test6'
],
]];
$values = array_column($array['level1'], 'attr2');
var_dump($values);
creates
array(2) {
[0]=>
string(5) "test2"
[1]=>
string(5) "test5"
}
You can use array_map for that :
$array = ['level1' => [
'item1' => [
'attr1' => 'test1',
'attr2' => 'test2',
'attr3' => 'test3'
],
'item2' => [
'attr1' => 'test4',
'attr2' => 'test5',
'attr3' => 'test6'
],
]];
// parse every item
$values = array_map(function($item) {
// for each item, return the value 'attr2'
return $item['attr2'];
}, $array['level1']);
I have created a sandbox for you to try;
Use foreach statement will be solved your case
$newarray = array();
foreach($array['level1'] as $randomItemKey => $randomItemValue){
$newarray[] = $randomItemValue['attr2'];
}
If the values can occur at any point in the array, you can use array_walk_recursive() which will loop through all of the values (only leaf nodes) and you can check if it is an attr2 element and add it into an output array...
$out = [];
array_walk_recursive($array, function ($data, $key ) use (&$out) {
if ( $key == "attr2" ) {
$out[] = $data;
}
});

Selecting value from array with a range?

I've an array on php that will return a lot of keys->values, like this:
Array
[0] => Array
(
[value] => 405
[information] => some information1
)
[1] => Array
(
[value] => 500
[information] => some information2
)
[2] => Array
(
[value] => 700
[information] => some information3
)
the values are numbers, i need to collect all the values, check the first one that will be >= $determinedvalue and then return the value "information" for this exactly array, is this even possible? I know i can do this if i create a temp table on my database, but i dont want to.
To be more clearly, when my value is "430" it will return me "some information2".
I've searched a lot on google but by now i dont know if this is even possible.
Appreciate any help.
This is a sample on how to do that. Comments in code can be used to explain the execution.
// Sample Array
$arr = array(
array
(
"value" => 405,
"information" => "some information1"
),
array
(
"value" => 500,
"information" => "some information2"
),
array
(
"value" => 700,
"information" => "some information3"
)
);
// Sample Number
$numberToCheck = 430;
// Sub Array To Assign
$subArray = array();
// Loop Through Outer Array
for ( $i = 0; $i < sizeof($arr); $i++)
{
// If Value In Array > Number Check
if ( $arr[$i]['value'] >= $numberToCheck )
{
$subArray = $arr[$i]; // Assign Sub Array
$i = sizeof($arr); // This is Used to Exit For Loop
}
}
print_r($subArray); // Print
Working runnable code: https://tech.io/snippet/QJ93AwV
Code snippent with comments:
<?php
/**
* Helper class for stable sort alogithms
* #see https://github.com/vanderlee/PHP-stable-sort-functions
* Class StableSort
*/
class StableSort
{
static public function usort(array &$array, $value_compare_func)
{
$index = 0;
foreach ($array as &$item) {
$item = array($index++, $item);
}
$result = usort($array, function ($a, $b) use ($value_compare_func) {
$result = call_user_func($value_compare_func, $a[1], $b[1]);
return $result == 0 ? $a[0] - $b[0] : $result;
});
foreach ($array as &$item) {
$item = $item[1];
}
return $result;
}
}
$array = [
// added for test sorting
[
'value' => 9999,
'information' => 'some information-1',
],
[
'value' => 1200,
'information' => 'some information0',
],
// \added for test sorting
[
'value' => 405,
'information' => 'some information1',
],
// added for test sorting stability
[
'value' => 405,
'information' => 'some information1.2',
],
[
'value' => 405,
'information' => 'some information1.1',
],
// \added for test sorting stability
[
'value' => 500,
'information' => 'some information2',
],
[
'value' => 700,
'information' => 'some information3',
],
];
// sort array
$determinedvalue = 430;
StableSort::usort($array, function ($item1, $item2) {
if ($item1['value'] == $item2['value']) return 0;
return $item1['value'] < $item2['value'] ? -1 : 1;
});
// then select the first element by condition
$res = null;
foreach($array as $v) {
if($v['value'] >= $determinedvalue) {
$res = $v['information'];
break;
}
}
// for testing
print $res;
$number = 430;
$array = Array
[0] => Array
(
[value] => 405
[information] => some information1
)
[1] => Array
(
[value] => 500
[information] => some information2
)
[2] => Array
(
[value] => 700
[information] => some information3
)
$firstArray = $array[0];
$secondArray = $array[1];
$threeArray = $array[2];
function selectValueFromArrayRange ($number, $start, $end, $value, $infomation)
{
$startValue = $start[$value];
$endValue = $end[$value];
if ( in_array($number, range($startValue, $endValue)) ) {
return $end[$infomation];
}
}
selectValueFromArrayRange($number, $firstArray, $secondValue, 'value', 'infomation')

Parse through unordered multidimensional array finding only strings

I have a multidimensional array of undefined depth.
$array = array(
"foo" => "bar",
42 => 24,
"multi" => array(
"dimensional" => array(
"array" => "foo",
"something" => 42,
"something2" => [1,2,3]
)
)
);
I need to parse through it, find all the values that are plane text and save them in another array keeping the pathway. So I expect the final array be like this:
$array = array(
"foo" => "bar",
"multi" => array(
"dimensional" => array(
"array" => "foo"
)
)
);
At the moment I'm trying to use recurrent function
$this->printAll($array);
public function printAll($a)
{
if (!is_array($a)) {
echo $a, ' <br>'; // here we can check if it is string and add to the final array
return;
}
foreach($a as $i=>$v) {
$this->printAll($v);
echo $i;
}
}
Could someone help me to figure out how to keep indexes through iterations and put it in the final array.
<?php
function printAll($array, &$save)
{
foreach ($array as $key => $values)
{
if ( ! is_numeric($values))
{
if (is_array($values))
{
printAll($values, $save[$key]);
}
else
{
$save[$key] = $values;
}
}
}
if ( ! empty($save)) {
$save = array_filter($save);
}
}
$array = array(
"foo" => "bar",
42 => 24,
"multi" => array(
"dimensional" => array(
"array" => "foo",
"something" => 42,
"something2" => [1,2,3]
)
)
);
$save = array();
printAll($array, $save);
print_r($save);
Outputs: PHP
Array (
[foo] => bar
[multi] => Array (
[dimensional] => Array (
[array] => foo
)))

Using PHP array iterator to edit array

I have a multidimensional array with variable number of levels of data. That is, I can't be sure how many iterations it will take to reach the Goal level, which is an array. Something like this:
[
'key1' = 'value1',
'key2' = 'value2',
'key3' = [
'key4' => [
'key5' => 'value3'
],
'key6' => 'value4'
],
'key7' => [
'Goal' => [
'value5',
'value6',
'value7'
]
],
'key8' => 'value8'],
'key9' => [
'Goal' => [
'value9',
'Foo',
'value10'
]
]
]
I've tried both array_walk_recursive and ArrayIterator, but neither seems to quite get me where I need to be.
I need to go through each element of the array, and if the key is Goal examine the value (eg. the array that Goal holds) and see if that array contains the value Foo.
If Foo is found in the array, I need to add a new value (in addition to Foo-- so call it Bar) to the array and then continue, since there may be more Goals in the parent array.
Is there a way to "stop" the iterator when we find a Goal, without iterating further, and then do the array_search operation?
Edit: Trying somethings along these lines--
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($iterator as $key => $value)
{
if($key == 'Goal')
{
if (is_array($value)) {
if(array_search('Foo', $value)) {
$value[] = 'Bar';
}
}
}
}
Not entirely sure if this is what you want to achieve but here's a solution which adds Bar to arrays nested in the Goal key:
$array = [
'key1' => 'value1',
'key2' => 'value2',
'key3' => [
'key4' => [
'key5' => 'value3',
],
'key6' => 'value4',
],
'key7' => [
'Goal' => [
'value5',
'value6',
'value7',
],
],
'key8' => 'value8',
'key9' => [
'Goal' => [
'value9',
'Foo',
'value10',
],
],
];
function iterate(array $data, $goal = false)
{
foreach ($data as $key => &$value) {
if (is_array($value)) {
$value = iterate($value, $key === 'Goal');
} elseif (is_string($value)) {
if (($value === 'Foo') && $goal) {
$data[] = 'Bar';
return $data;
}
}
}
return $data;
}
var_export(iterate($array));
The code generates the following output:
array (
'key1' => 'value1',
'key2' => 'value2',
'key3' =>
array (
'key4' =>
array (
'key5' => 'value3',
),
'key6' => 'value4',
),
'key7' =>
array (
'Goal' =>
array (
0 => 'value5',
1 => 'value6',
2 => 'value7',
),
),
'key8' => 'value8',
'key9' =>
array (
'Goal' =>
array (
0 => 'value9',
1 => 'Foo',
2 => 'value10',
3 => 'Bar',
),
),
)
Iterators in my opinion would be weird to use in these kind of arrays... I would do it with something like this:
/*
Usage:
$wasFound = checkArray( "Goal", "Foo", $the_array);
if ( $wasFound ) echo "Key and Value pair found in the array!";
else { /* not found */ }
*/
function checkArray( $key_to_find, $value_to_find, $my_var, $last_key = NULL ) {
$found = FALSE;
if ( $last_key == $key_to_find && $my_var == $value_to_find )
return TRUE;
if ( $my_var == NULL )
return FALSE;
if ( is_array( $my_var ) ) {
foreach ( $my_var AS $key => $value )
{
if ( $found ) {
/* Do something else if needed when found */
break;
}
$found = checkArray( $key_to_find, $value_to_find, $value, $key );
}
}
return $found;
}
I agree that recursion is the way to do this. The problem with using array_walk_recursive is that you will not be able to see the Goal key, because as per the PHP documentation,
Any key that holds an array will not be passed to the function.
I am not really sure whether using a RecursiveIteratorIterator would be better than just writing a recursive function for it. A function for something like this should be fairly simple.
function addBar(&$array) {
foreach ($array as $key => &$value) {
if ($key === 'Goal') {
if(array_search('Foo', $value)) {
$value[] = 'Bar';
}
} elseif (is_array($value)) {
addBar($value);
}
}
}
This function takes a reference to your array, so it will update your actual array rather than creating a copy with Bar added to each Goal.

How to compare three values in a array and merge?

How can i merge array with the same value?
I have three array which are $participants, $conferance_participants and $contacts
i want to compare values with this three array and merge
for example :
if $participants['calleridnum'] == $conferance_participants['uid'] == $contacts['name']
i want the output to be like this :
Array
(
[0] => Array
(
[calleridnum] => 1
[test] => yay
[uid] => 1
[channel] => deze
[name] => 1
[limit] => 1
)
)
this is my code so far:
<?php
$participants = [
[ 'calleridnum' => 1,
'test' => 'yay'
]
];
$conferance_participants = [
[ 'uid' => 1,
'test' => 'yay2',
'channel' => 'deze'
]
];
$contacts = [
[ 'name' => 1,
'test' => 'yay2',
'limit' => 1
]
];
foreach ($participants as $participant=>$p) {
foreach ($conferance_participants as $conferance_participant=>$c) {
foreach ($contacts as $contact=>$cs) {
if (($p['calleridnum'] == $c['uid']) && ($c['uid'] == $cs['name'])) {
foreach ( $c as $key=>$val ) {
if (!isset($p[$key])) {
$participants[$participant][$key] = $val;
}
}
}
}
}
}
print_r( $participants );
?>
Try to call array_merge() , but you still have to consider the different values with the same key (eg. the values of key 'test' )
if (($p['calleridnum'] == $c['uid']) && ($p['uid'] == $c['name'])) {
$participants[$participant] = array_merge(
$participants[$participant],
$conferance_participants[$conferance_participant],
$contacts[$contact]
);
}

Categories