How to extract specific key string from array in php? - php

This is my array
Array
(
[question_set] => Computer Basics
[question] => Who are You ?
[options_1] => RK
[options_2] => KAMAL
[options_3] => DPK
[options_4] => NARENDRA
[marks] => 5
[negative_marks] => 1
[type] => 1
)
options_ are dynamic means it can be 4, 6 or 8.
I want to get value "options" from key of options_1 or so on. How can I do this.

strpos is way faster than preg_match, for reference: strpos() vs preg_match()
Using foreach and strpos() :
$arr = array(
"question_set" => "Computer Basics",
"question" => "Who are You ?",
"options_1" => "RK",
"options_2" => "KAMAL",
"options_3" => "DPK",
"options_4" => "NARENDRA",
"marks" => 5,
"negative_marks" => 1,
"type" => 1
);
$newArr = array();
foreach($arr as $key => $value) {
if(strpos($key, "options") !== false) {
$newArr[$key] = $value;
}
}
echo '<pre>';
var_dump($newArr);
echo '</pre>';

<?php
$array = array("options_1" => "RK",
"options_213" => "21313",
"options_4" => "NARENDRA",
"foo" => "bar", 5 , 5 => 89009,
);
$pattern = "/\boptions/";
foreach($array as $key => $value) {
if (preg_match($pattern,$key)){
echo $key."\t=>\t".$value."\n";
}
}

Related

move array keys to another array

i have an array like this :
$post = array(
"name" => "John",
"user" => "1" ,
"title" => "hello" ,
"uploader_0_name" => "pic.jpg",
"uploader_0_status" => "done",
"uploader_1_name" => "aaaa.jpg",
"uploader_1_status" => "done",
"uploader_2_name" => "Tulips.jpg",
"uploader_2_status" => "failed",
"uploader_count" => "3"
);
i want to have uploader_[/d]_name and uploader_[/d]_name in another array like example :
[0] => Array
(
[name] => pic.jpg
[status] => done
)
[1] => Array
(
[name] => aaaa.jpg
[status] => done
)
[2] => Array
(
[name] => Tulips.jpg
[status] => failed
)
in this case array with index 0 should have uploader_0_name,uploader_0_status
i tried a lot to do this with preg_match in foreach loop , but i could not be successful
foreach ( $post as $key => $value ) {
$pattern = "/^uploader_[\d]_(name|status)$/";
preg_match( $pattern , $key ,$matches[]);
}
P.S : Unfortunately today i seen the best answer and the best way was deleted ,so i added it , if any one have problem like this , can use :
foreach ($post as $key => $value) {
if (preg_match('/^uploader_(\d)_(name|status)$/', $key, $matches)) {
$result[$matches[1]][$matches[2]] = $value;
}
}
try this if you dont want to use regular expressions:
$newArr = array();
foreach($post as $key => $val) {
$newKey = explode("_", $key);
if (count($newKey) > 2) {
//this is the status
$innerValue = array_pop($newKey);
//this is the numeric ID _2_ for example
$innerKey = array_pop($newKey);
$newArr[$innerKey][$innerValue] = $val;
}
}
There is a simple way to do this do not use hard structures:
$post = array(
"name" => "John",
"user" => "1" ,
"title" => "hello" ,
"uploader_0_name" => "pic.jpg",
"uploader_0_status" => "done",
"uploader_1_name" => "aaaa.jpg",
"uploader_1_status" => "done",
"uploader_2_name" => "Tulips.jpg",
"uploader_2_status" => "failed",
"uploader_count" => "3"
);
//result array;
$arr = array();
//counter
$n = 0;
foreach ($post as $key => $value) {
if(strpos($key, '_name') != false){
$arr[$n]['name'] = $value;
}elseif(strpos($key, '_status') != false){
$arr[$n]['status'] = $value;
$n++;
}
}
print_r($arr);

How to filter any array by key text(name)?

I want to filter array by the key's text.
Suppose I have an array like:
Array
(
[FAR] =>
[NEAR] => 1
[IMMEDIATE] =>
[FAR_beacon_location] =>
[FAR_test] =>
[FAR_test2] =>
[NEAR_test] => 6
[NEAR_test2] => 6
)
From this array I just want the elements whose key's text starts with NEAR.
How do I do that?
try this code.
$res_arr = array();
foreach($my_array as $key=>$val) {
if(strpos($key, "NEAR") === 0) {
//Key matches,
$res_arr[] = $val;
}
}
print_r($res_arr);
Do like this..
<?php
$arr=Array
(
'FAR' => '',
'NEAR' => 1,
'IMMEDIATE' =>'',
'FAR_beacon_location' =>'',
'FAR_test' => '',
'FAR_test2' =>'',
'NEAR_test' => 6,
'NEAR_test2' => 6
);
foreach($arr as $k=>$v)
{
if(substr($k, 0, 4)!='NEAR')
{
unset($arr[$k]);
}
}
echo "<pre>";
print_r($arr);
OUTPUT :
Array
(
[NEAR] => 1
[NEAR_test] => 6
[NEAR_test2] => 6
)
function is_NEAR($var)
{
return strpos($var, "NEAR") === 0;
}
print_r(array_flip(array_filter(array_flip($arr), "is_NEAR")));
$array=Array
(
[FAR] =>
[NEAR] => 1
[IMMEDIATE] =>
[FAR_beacon_location] =>
[FAR_test] =>
[FAR_test2] =>
[NEAR_test] => 6
[NEAR_test2] => 6
)
foreach($array as $key=>$value)
{
if(strpos($key,"NEAR")==0)
{
// do your task
}
}

Nested array to single array keeping the parents

The problem is to change a tree structure to a simple array structure, in which each child has the parents who belongs to, the example is a directories and files structure, but I'm looking for a generic solution.
If the writing is bad, feel free to improve it.
Any help is welcome.
Example.
$array_1=array(
'f1' =>
array(
'f2' =>array('file1.php','file2.php'),
'f3' =>array('file3.php','file4.php'),
'f4' =>
array(
'fol5'=>
array('fileAA.php','fileBB.php')
,
'fileDD.php'
),
),
'f2' =>
array(
'f2' =>array('file1.php','file2.php'),
'f3' =>array('file3.php'),
)
);
The result should be like this:
/*
0 => '/f1/f2/file1.php',
1 => '/f1/f2/file2.php',
2 => '/f1/f3/file3.php',
3 => '/f1/f3/file4.php',
4 => '/f1/f4/fol5/fileAA.php',
5 => '/f1/f4/fol5/fileBB.php',
6 => '/f1/f4/fileDD.php',
7 => '/f2/f2/file1.php',
8 => '/f2/f2/file2.php',
9 => '/f2/f3/file3.php',
*/
here is simple recursive function:
function tree2array($input, &$output, $prefix = '')
{
foreach ($input as $i => $v)
if (is_array($v))
tree2array($v, $output, $prefix.'/'.$i);
else
$output[] = $prefix.'/'.$v;
}
usage:
tree2array($array_1, $array2);
output:
print_r($array2);
Array (
[0] => /f1/f2/file1.php
[1] => /f1/f2/file2.php
[2] => /f1/f3/file3.php
[3] => /f1/f3/file4.php
[4] => /f1/f4/fol5/fileAA.php
[5] => /f1/f4/fol5/fileBB.php
[6] => /f1/f4/fileDD.php
[7] => /f2/f2/file1.php
[8] => /f2/f2/file2.php
[9] => /f2/f3/file3.php )
I made an alternative solution using SPL
$arrayiter = new RecursiveArrayIterator($array_1);
$iteriter = new RecursiveIteratorIterator($arrayiter,RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iteriter as $key => $value) {
$this_depth = $iteriter->getDepth();
if(!is_array($value)){
$array_2[] = '/'.$value;
$level[]=$this_depth;
}
foreach($array_2 as $key2 => $value2){
if($this_depth < $level[$key2]){
$level[$key2] = $this_depth;
$array_2[$key2] = '/'.$key.$value2;
}
}
}
echo'<pre>';
print_r($array_2);
echo'</pre>';

how to change a key in an array while maintaining the order? [duplicate]

This question already has answers here:
Change array key without changing order
(8 answers)
Closed 7 years ago.
How i can do this:
$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array
// rename $array['d'] as $array['b']
$array = replace_key_function($array, 'd', 'b');
var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!
I didn't see a function that does that.
There is a way to do this?
http://ideone.com/nCZnY
$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array
// rename $array['d'] as $array['b']
$array = replace_key_function($array, 'd', 'b');
var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!
function replace_key_function($array, $key1, $key2)
{
$keys = array_keys($array);
$index = array_search($key1, $keys);
if ($index !== false) {
$keys[$index] = $key2;
$array = array_combine($keys, $array);
}
return $array;
}
There is a flaw in the logic of the accepted answer.
If you have an array like this:
[
'k1'=>'k1',
'k2'=>'k2',
'k3',
'k4'=>'k4'
]
and replace 'k4' with 'something' you will get an output like this:
[
'k1'=>'k1',
'k2'=>'k2',
'something' => 'k3',
'k4'=>'k4'
]
Here is a quick fix that solves the problem:
function replace_key_function($array, $key1, $key2)
{
$keys = array_keys($array);
//$index = array_search($key1, $keys);
$index = false;
$i = 0;
foreach($array as $k => $v){
if($key1 === $k){
$index = $i;
break;
}
$i++;
}
if ($index !== false) {
$keys[$index] = $key2;
$array = array_combine($keys, $array);
}
return $array;
}
EDIT:2014/12/03
The accepted answer does work if you set the third parameter (strict) of array_search to true.
Instead of using loops, you could always flatten to string with json_encode(), perform a string replacement, then json_decode() back to an array:
function replaceKey($array, $old, $new)
{
//flatten the array into a JSON string
$str = json_encode($array);
// do a simple string replace.
// variables are wrapped in quotes to ensure only exact match replacements
// colon after the closing quote will ensure only keys are targeted
$str = str_replace('"'.$old.'":','"'.$new.'":',$str);
// restore JSON string to array
return json_decode($str, TRUE);
}
Now this doesn't check for conflicts with pre-existing keys (easy enough to add a string comparison check), and it might not be the best solution for single replacements in massive arrays.. but the nice part about flattening the array into a string for replacement is that it effectively makes replacement recursive since matches at any depth are all replaced in one pass:
$arr = array(
array(
'name' => 'Steve'
,'city' => 'Los Angeles'
,'state' => 'CA'
,'country' => 'USA'
,'mother' => array(
'name' => 'Jessica'
,'city' => 'San Diego'
,'state' => 'CA'
,'country' => 'USA'
)
)
,array(
'name' => 'Sara'
,'city' => 'Seattle'
,'state' => 'WA'
,'country' => 'USA'
,'father' => array(
'name' => 'Eric'
,'city' => 'Atlanta'
,'state' => 'GA'
,'country' => 'USA'
,'mother' => array(
'name' => 'Sharon'
,'city' => 'Portland'
,'state' => 'OR'
,'country' => 'USA'
)
)
)
);
$replaced = replaceKey($arr,'city','town');
print_r($replaced);
outputs
Array
(
[0] => Array
(
[name] => Steve
[town] => Los Angeles
[state] => CA
[country] => USA
[mother] => Array
(
[name] => Jessica
[town] => San Diego
[state] => CA
[country] => USA
)
)
[1] => Array
(
[name] => Sara
[town] => Seattle
[state] => WA
[country] => USA
[father] => Array
(
[name] => Eric
[town] => Atlanta
[state] => GA
[country] => USA
[mother] => Array
(
[name] => Sharon
[town] => Portland
[state] => OR
[country] => USA
)
)
)
)
A generic and simple solution with PHP 5.3+ using array_walk:
$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array
$array = replace_keys($array, array('d' => 'b'));
var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!
function replace_keys(array $source, array $keyMapping) {
$target = array();
array_walk($source,
function ($v, $k, $keyMapping) use (&$target) {
$mappedKey = isset($keyMapping[$k]) ? $keyMapping[$k] : $k;
$target[$mappedKey] = $v;
},
$keyMapping);
return $target;
}
a good answer has been posted, but here's my two pence:
$array = array('a'=>1, 'd'=>2, 'c'=>3);
// rename 'd' to 'b'
foreach($array as $k=>$v){
if($k == 'd') { $k='b'; }
$newarray[$k] = $v;
}
$array = $newarray;
in response to mike-purcell would this be a more accepted approach to my example above?
changeKey($array, 'd', 'b');
function changeKey($array, $oldKey, $newKey)
{
foreach($array as $k=>$v){
if($k == $oldKey) { $k = $newKey; }
$returnArray[$k] = $v;
}
return $returnArray;
}
I'm always looking to improve :)

How to merge these two array?

These are my two arrays:
$test = array(
"0" => array(
"mem_id" => "299",
"profilenam" => "Guys&Dolls",
"photo_b_thumb" => "photos/935a89f58ef2f3c7aaaf294cb1461d64bth.jpeg"
),
"1" => array(
"mem_id" => "344",
"profilenam" => "Dmitry",
"photo_b_thumb" => "no")
);
$distance = array(
"0" => "0",
"1" => "3.362",
"2" => "0.23"
);
I want to combine them as:
Array
(
[0] => Array
(
[mem_id] => 299
[profilenam] => Guys&Dolls
[photo_b_thumb] => photos/935a89f58ef2f3c7aaaf294cb1461d64bth.jpeg
[distance] => 3.362
)
[1] => Array
(
[mem_id] => 344
[profilenam] => Dmitry
[photo_b_thumb] => no
[distance] => 0.23
)
)
I tried the code below but it did not work:
foreach ($test as $key => $value) {
$merged = array_merge((array) $value, $distance);
}
print_r($merged);
<?php
foreach($test as $index=>$array)
{
$test[$index]['distance'] = $distance[$index]
}
print_r($test);
?>
$test = array("0" => array("mem_id" => "299", "profilenam" => "Guys&Dolls", "photo_b_thumb" => "photos/935a89f58ef2f3c7aaaf294cb1461d64bth.jpeg"
), "1" => array("mem_id" => "344", "profilenam" => "Dmitry", "photo_b_thumb" => "no"));
$distance = array("0" => "0", "1" => "3.362", "2" => "0.23");
foreach( $test as $id => $data ) {
$test[$id]['distance'] = $distance[$id];
}
Something like this should work!
foreach ($test as $key => &$value) {
$value["distance"] = $distance[$key];
}
I think array_merge_recursive does what you need.
EDIT: It does not. :) However, a derivate of it, posted in the array_map_recursive man page does seem to, see this codepad. I'd be interested to know which is faster over a large dataset.
foreach ($test as &$value)
{
$value['distance'] = array_shift($distance);
}

Categories