This question already has answers here:
PHP multidimensional array search by value
(23 answers)
Closed 5 years ago.
Alright, so I'm querying the DB and generating an array from a list of IP addresses:
$q = 'SELECT ip FROM proxy';
$r = mysqli_fetch_all($con->query($q), MYSQLI_ASSOC);
Array returned looks like this:
Array
(
[0] => Array
(
[ip] => 1.202.244.222
)
[1] => Array
(
[ip] => 1.226.238.136
)
[2] => Array
(
[ip] => 1.228.231.247
)
[3] => Array
(
[ip] => 1.238.106.137
)
[4] => Array
(
[ip] => 1.238.155.191
)
But if I want to find say the first or any IP in the above list, for some reason it doesn't find anything:
$ip = "1.202.244.222";
if(in_array($ip,$r)) {
echo "gotcha";
}
What am I doing wrong here?
Got confused by the array within array stuff which I didn't notice at first.
Thanks to Zeth's pointers, I got it to work by collapsing the arrays into one by adding:
$r0 = array_column($r, 'ip');
And then:
if(in_array($ip,$r0)) {
echo "gotcha";
}
It's an array of arrays... Collapse the thing, and then it'll work. There are a couple of options here: How to "flatten" a multi-dimensional array to simple one in PHP?
The most flexible approach for such situations is to use a user defined comparison function:
<?php
$needle = '1.202.244.222';
$haystack = [
[
'ip' => '1.202.244.222'
],
[
'ip' => '1.226.238.136'
],
[
'ip' => '1.228.231.247'
],
[
'ip' => '1.238.106.137'
],
[
'ip' => '1.238.155.191'
]
];
$result = array_filter($haystack, function($entry) use ($needle) {
return isset($entry['ip']) && $needle === $entry['ip'];
});
print_r($result);
The output of above code obviously is:
Array
(
[0] => Array
(
[ip] => 1.202.244.222
)
)
Your Array condition was wrong.
$ip_find = '1.202.244.222';
$ip_values = [
[
'ip' => '1.202.244.222'
],
[
'ip' => '1.226.238.136'
],
[
'ip' => '1.228.231.247'
],
[
'ip' => '1.238.106.137'
],
[
'ip' => '1.238.155.191'
]
];
foreach ($ip_values as $key => $value) {
foreach ($value as $key => $ip) {
if ($ip==$ip_find) {
echo $ip." Gocha";
break;
}
}
}
You can do it using foreach:
$r = [
[
'ip' => '1.202.244.222'
],
[
'ip' => '1.226.238.136'
],
[
'ip' => '1.228.231.247'
],
[
'ip' => '1.238.106.137'
],
[
'ip' => '1.238.155.191'
]
];
$ip = "1.202.244.222";
foreach($r as $elem)
{
if($elem['ip'] == $ip)
{
echo "gotcha";
break;
}
}
Related
What is the best method to remove commas from numbers in the associative array below? Keep the commas in text, thanks.
$main_arr contains the following 3 arrays:
Array
(
[phrase] => Hi, I'm ok
[number_a] => 3,575
[number_b] => 64
[number_c] => 8,075
)
Array
(
[phrase] => Bye, it's late
[number_a] => 7,365
[number_b] => 32
[number_c] => 648,120
)
Array
(
[phrase] => Good catch!
[number_a] => 11,659
[number_b] => 128
[number_c] => 1,492,352
<?php
$mainArray =[
[
'phrase' => "Hi, I'm ok",
'number_a' => "3,575",
'number_b' => "64",
'number_c' => "8,075",
],
[
'phrase' => "Bye, it's late",
'number_a' => "7,365",
'number_b' => "32",
'number_c' => "648,120",
],
[
'phrase' => 'Good catch!',
'number_a' => "11,659",
'number_b' => "128",
'number_c' => "1,492,352",
],
];
foreach($mainArray as &$array) {
foreach($array as &$val) {
if (preg_match('/^[0-9,]*$/', $val)){
$val = str_replace(',','',$val);
}
}
}
var_export($mainArray);
This question already has answers here:
How to access and manipulate multi-dimensional array by key names / path?
(10 answers)
Closed 2 years ago.
I'm trying to get reach a point in a dynamicly generated multidimensional array based on a array with keys.
Basicly I have the following array:
$arr = [
"something" => [
'something_else' => [
"another_thing" => "boo"
]
],
"something2" => [
'something_elseghf' => [
"another_thingfg" => [
"hi" => "bye"
]
]
],
"info" => [
'something_else2' => [
"another_thingh" => "boo"
]
],
];
Now I want to set a value in the array based on the keys in a different array:
$keyArr = ["something2", 'something_elseghf' "another_thingfg", "hi"];
So the above array means that I need to set the hi key to some value. How can I reach that part of the array with these random keys, note that the length of $keyArr is dynamic aswell. So I can't reach it with:
$arr[$keyArr[0]][$keyArr[1]][$keyArr[2]][$keyArr[3]] =
Hope anyone has an idea on how to solve this!
Try this approach:
$arr = [
"something" => [
'something_else' => [
"another_thing" => "boo"
]
],
"something2" => [
'something_elseghf' => [
"another_thingfg" => [
"hi" => "bye"
]
]
],
"info" => [
'something_else2' => [
"another_thingh" => "boo"
]
],
];
$keyArr = ["something2", 'something_elseghf', "another_thingfg", "hi"];
$cursor = $arr;
foreach ($keyArr as $key) {
$cursor = $cursor[$key];
}
echo $cursor;
Will echo
bye
UPDATE:
If you want to change a value within multi-dimentional array, then use a recursive function, like this:
function changeValue($array, $path, $value) {
if (empty($path)) {
return $value;
}
$key = array_shift($path);
$array[$key] = changeValue($array[$key], $path, $value);
return $array;
}
$arr = [
"something" => [
'something_else' => [
"another_thing" => "boo"
]
],
"something2" => [
'something_elseghf' => [
"another_thingfg" => [
"hi" => "bye"
]
]
],
"info" => [
'something_else2' => [
"another_thingh" => "boo"
]
],
];
$keyArr = ["something2", 'something_elseghf', "another_thingfg", "hi"];
$changedArray = changeValue($arr, $keyArr, 'New value!');
print_r($changedArray);
Will output
Array
(
[something] => Array
(
[something_else] => Array
(
[another_thing] => boo
)
)
[something2] => Array
(
[something_elseghf] => Array
(
[another_thingfg] => Array
(
[hi] => New value!
)
)
)
[info] => Array
(
[something_else2] => Array
(
[another_thingh] => boo
)
)
)
I need to perform iterated explosions on values in one column of my two dimensional array, then re-group the data to flip the relational presentation from "tag name -> video id" to "video id -> tag name".
Here is my input array:
$allTags = [
[
"name" => "TAG-ONE",
"video" => "64070,64076,64110,64111",
],
[
"name" => "TAG-TWO",
"video" => "64070,64076,64110,64111",
],
[
"name" => "TAG-THREE",
"video" => "64111",
]
];
I want to isolate unique video ids and consolidate all tag names (as comma-separayed values) that relate to each video id.
Expected output:
$allTagsResult = [
[
"name" => "TAG-ONE,TAG-TWO",
"video" => "64070",
],
[
"name" => "TAG-ONE,TAG-TWO",
"video" => "64076",
],
[
"name" => "TAG-ONE,TAG-TWO",
"video" => "64110",
],
[
"name" => "TAG-ONE,TAG-TWO,TAG-THREE",
"video" => "64111",
],
];
Somehow I did it by checking the value using nested loops but I wish to know if you guys can suggest any shortest method to get the expected output.
If you want to completely remove foreach() loops, then using array_map(), array_walk_recursive(), array_fill_keys() etc. can do the job. Although I think that a more straightforward answer using foreach() would probably be faster, but anyway...
$out1 = array_map(function ($data) {
return array_fill_keys(explode(",", $data['video']), $data['name']); },
$allTags);
$out2 = [];
array_walk_recursive( $out1, function ( $data, $key ) use (&$out2) {
if ( isset($out2[$key])) {
$out2[$key]['name'] .= ",".$data;
}
else {
$out2[$key] = [ 'name' => $data, 'video' => $key ];
}
} );
print_r($out2);
will give...
Array
(
[64070] => Array
(
[name] => TAG-ONE,TAG-TWO
[video] => 64070
)
[64076] => Array
(
[name] => TAG-ONE,TAG-TWO
[video] => 64076
)
[64110] => Array
(
[name] => TAG-ONE,TAG-TWO
[video] => 64110
)
[64111] => Array
(
[name] => TAG-ONE,TAG-TWO,TAG-THREE
[video] => 64111
)
)
if you want to remove the keys, then
print_r(array_values($out2));
The code could be compressed by piling all of the code onto single lines, but readability is more useful sometimes.
Another method if you don't like looping:
$video_ids = array_flip(array_unique(explode(",",implode(",",array_column($allTags,'video')))));
$result = array_map(function($id){
return ['name' => '','video' => $id];
},array_flip($video_ids));
array_walk($allTags,function($tag_data) use (&$result,&$video_ids){
$ids = explode(",",$tag_data['video']);
foreach($ids as $id) $result[$video_ids[$id]]['name'] = empty($result[$video_ids[$id]]['name']) ? $tag_data['name'] : $result[$video_ids[$id]]['name'] . "," . $tag_data['name'];
});
Demo: https://3v4l.org/vlIks
Below is one way of doing it.
$allTags = [
'0' => [
"name" => "TAG-ONE",
"video" => "64070,64076,64110,64111",
],
'1' => [
"name" => "TAG-TWO",
"video" => "64070,64076,64110,64111",
],
'2' => [
"name" => "TAG-THREE",
"video" => "64111",
]
];
$allTagsResult = array();
$format = array();
foreach( $allTags as $a ) {
$name = $a['name'];
$videos = explode(',', $a['video']);
foreach( $videos as $v ) {
if( !isset( $format[$v]) ) {
$format[$v] = array();
}
$format[$v][] = $name;
}
}
foreach( $format as $video => $names) {
$allTagsResult[] = array('name' => implode(',', $names), 'video' => $video);
}
echo '<pre>';
print_r($allTagsResult);
die;
You can check Demo
I am typically in favor of functional style coding, but for this task I feel it only serves to make the script harder to read and maintain.
Use nested loops and explode the video strings, then group by those video ids and concatenate name strings within each group. When finished iterating, re-index the array.
Code: (Demo)
$result = [];
foreach ($allTags as $tags) {
foreach (explode(',', $tags['video']) as $id) {
if (!isset($result[$id])) {
$result[$id] = ['video' => $id, 'name' => $tags['name']];
} else {
$result[$id]['name'] .= ",{$tags['name']}";
}
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'video' => '64070',
'name' => 'TAG-ONE,TAG-TWO',
),
1 =>
array (
'video' => '64076',
'name' => 'TAG-ONE,TAG-TWO',
),
2 =>
array (
'video' => '64110',
'name' => 'TAG-ONE,TAG-TWO',
),
3 =>
array (
'video' => '64111',
'name' => 'TAG-ONE,TAG-TWO,TAG-THREE',
),
)
I am looping through instances of associative arrays (these associative arrays themselves are part of an array).
For each array I want to return a value, based on a key.
Currently I have:
$image_path = array_column($myarray, 'uri');
But of course array_column stores its values in a array, which, considering it's only returning 1 value, is useless to me.
Is there an existing function that will allow me to just get a value based off a supplied key?
Eg:
$image_path = get_keys_value($myarray, 'uri');
Example array. This is a very basic example. The real thing has many levels to it:
$myarray = array
(
'instance' => array(
'type' => 'somedata',
'content' => somedata',
'image' => array(
'name' => 'photo',
'uri' => 'path/to/file.png'
),
),
);
Desired outcome:
$image_path contains 'path/to/file.png' string.
Try this,
function array_column_recursive(array $haystack, $needle)
{
$found = [];
array_walk_recursive($haystack, function ($value, $key) use (&$found, $needle) {
if ($key == $needle) {
$found[] = $value;
}
});
return $found;
}
echo array_column_recursive($myarray, 'uri')[0];
Here is working code.
array_column will work with only 2 level array structure.
Above array will solve your problem.
I hope this will help
I guess you can use array_map.
Ex:
$arr = [
[
'root' => [
'child1' => [
'child2' => 123
]
]
],
[
'root' => [
'child1' => [
'child2' => 456
]
]
],
[
'root' => [
'child1' => [
'child2' => 789
]
]
],
[
'root' => [
'child1' => [
'child2' => 123
]
]
],
];
print_r(array_map(function($row) {
// here goes expression to get required path
return $row['root']['child1']['child2'];
}, $arr));
Output:
Array
(
[0] => 123
[1] => 456
[2] => 789
[3] => 123
)
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]
);
}