get array value when comparing it - php

I have 2 arrays fruit
Array(
[0]=>'Apple',
[1]=>'orange',
[2]=>'guava'
)
and second array is Allfruits
Array(
[0]=>'Strawberry',
[1]=>'Manggo',
[2]=>'durian',
[3]=>'Apple',
[4]=>'guava')
And then an empty array call $data
My question is how to insert members of Allfruits when it not exists in fruit array?
So with this example, i want the result is all fruit except Apple and guava inside data array any sugestion?

Here is a simple way of doing that
$items_to_add = array_diff($array_fruit, $array_all_fruit);
$exclude_existing = array_diff($array_all_fruit, $array_fruit);
$new_array = array_merge($items_to_add, $exclude_existing);

By using below function, you can merge 2arrays without duplicate
function mergeArrayIfNotExist($childArray, $parentArray) {
for ($i = 0; $i < sizeof($childArray), $i++) {
if (!in_array($childArray[$i], $parentArray)) {
array_push($parentArray, $childArray[$i]);
}
}
return $parentArray;
}

Just run a loop and search the value in the $data array. If it is in the array then get it's index by using array_search function and unset the value, otherwise add the value in $data array. Finally re-index the array if you need.
$check = ['Apple','orange','guava'];
$data = ['Strawberry','Manggo','durian','Apple','guava'];
foreach ($check as $key => $value) {
if(( $index = array_search( $value, $data )) !== false ){
unset( $data[$index] );
}else{
$data[] = $value;
}
}
$data = array_values( $data ); //for re-indexing the array

Related

PHP make a multidimensional associative array from key names in a string separated by brackets

I have a string with a variable number of key names in brackets, example:
$str = '[key][subkey][otherkey]';
I need to make a multidimensional array that has the same keys represented in the string ($value is just a string value of no importance here):
$arr = [ 'key' => [ 'subkey' => [ 'otherkey' => $value ] ] ];
Or if you prefer this other notation:
$arr['key']['subkey']['otherkey'] = $value;
So ideally I would like to append array keys as I would do with strings, but that is not possible as far as I know. I don't think array_push() can help here. At first I thought I could use a regex to grab the values in square brackets from my string:
preg_match_all( '/\[([^\]]*)\]/', $str, $has_keys, PREG_PATTERN_ORDER );
But I would just have a non associative array without any hierarchy, that is no use to me.
So I came up with something along these lines:
$str = '[key][subkey][otherkey]';
$value = 'my_value';
$arr = [];
preg_match_all( '/\[([^\]]*)\]/', $str, $has_keys, PREG_PATTERN_ORDER );
if ( isset( $has_keys[1] ) ) {
$keys = $has_keys[1];
$k = count( $keys );
if ( $k > 1 ) {
for ( $i=0; $i<$k-1; $i++ ) {
$arr[$keys[$i]] = walk_keys( $keys, $i+1, $value );
}
} else {
$arr[$keys[0]] = $value;
}
$arr = array_slice( $arr, 0, 1 );
}
var_dump($arr);
function walk_keys( $keys, $i, $value ) {
$a = '';
if ( isset( $keys[$i+1] ) ) {
$a[$keys[$i]] = walk_keys( $keys, $i+1, $value );
} else {
$a[$keys[$i]] = $value;
}
return $a;
}
Now, this "works" (also if the string has a different number of 'keys') but to me it looks ugly and overcomplicated. Is there a better way to do this?
I always worry when I see preg_* and such a simple pattern to work with. I would probably go with something like this if you're confident in the format of $str
<?php
// initialize variables
$str = '[key][subkey][otherkey]';
$val = 'my value';
$arr = [];
// Get the keys we want to assign
$keys = explode('][', trim($str, '[]'));
// Get a reference to where we start
$curr = &$arr;
// Loops over keys
foreach($keys as $key) {
// get the reference for this key
$curr = &$curr[$key];
}
// Assign the value to our last reference
$curr = $val;
// visualize the output, so we know its right
var_dump($arr);
I've come up with a simple loop using array_combine():
$in = '[key][subkey][otherkey][subotherkey][foo]';
$value = 'works';
$output = [];
if(preg_match_all('~\[(.*?)\]~s', $in, $m)) { // Check if we got a match
$n_matches = count($m[1]); // Count them
$tmp = $value;
for($i = $n_matches - 1; $i >= 0; $i--) { // Loop through them in reverse order
$tmp = array_combine([$m[1][$i]], [$tmp]); // put $m[1][$i] as key and $tmp as value
}
$output = $tmp;
} else {
echo 'no matches';
}
print_r($output);
The output:
Array
(
[key] => Array
(
[subkey] => Array
(
[otherkey] => Array
(
[subotherkey] => Array
(
[foo] => works
)
)
)
)
)
Online demo

Compare and replace values in array

I need compare 2 arrays , the first array have one order and can´t change , in the other array i have different values , the first array must compare his id with the id of the other array , and if the id it´s the same , take the value and replace for show all in the same order
For Example :
$array_1=array("1a-dogs","2a-cats","3a-birds","4a-people");
$array_2=array("4a-walking","2a-cats");
The Result in this case i want get it´s this :
"1a-dogs","2a-cats","3a-birds","4a-walking"
If the id in this case 4a it´s the same , that entry must be modificate and put the value of other array and stay all in the same order
I do this but no get work me :
for($fte=0;$fte<count($array_1);$fte++)
{
$exp_id_tmp=explode("-",$array_1[$fte]);
$cr_temp[]="".$exp_id_tmp[0]."";
}
for($ftt=0;$ftt<count($array_2);$ftt++)
{
$exp_id_targ=explode("-",$array_2[$ftt]);
$cr_target[]="".$exp_id_targ[0]."";
}
/// Here I tried use array_diff and others but no can get the results as i want
How i can do this for get this results ?
Maybe you could use the array_udiff_assoc() function with a callback
Here you go. It's not the cleanest code I've ever written.
Runnable example: http://3v4l.org/kUC3r
<?php
$array_1=array("1a-dogs","2a-cats","3a-birds","4a-people");
$array_2=array("4a-walking","2a-cats");
function getKeyStartingWith($array, $startVal){
foreach($array as $key => $val){
if(strpos($val, $startVal) === 0){
return $key;
}
}
return false;
}
function getMergedArray($array_1, $array_2){
$array_3 = array();
foreach($array_1 as $key => $val){
$startVal = substr($val, 0, 2);
$array_2_key = getKeyStartingWith($array_2, $startVal);
if($array_2_key !== false){
$array_3[$key] = $array_2[$array_2_key];
} else {
$array_3[$key] = $val;
}
}
return $array_3;
}
$array_1 = getMergedArray($array_1, $array_2);
print_r($array_1);
First split the 2 arrays into proper key and value pairs (key = 1a and value = dogs). Then try looping through the first array and for each of its keys check to see if it exists in the second array. If it does, replace the value from the second array in the first. And at the end your first array will contain the result you want.
Like so:
$array_1 = array("1a-dogs","2a-cats","3a-birds","4a-people");
$array_2 = array("4a-walking","2a-cats");
function splitArray ($arrayInput)
{
$arrayOutput = array();
foreach ($arrayInput as $element) {
$tempArray = explode('-', $element);
$arrayOutput[$tempArray[0]] = $tempArray[1];
}
return $arrayOutput;
}
$arraySplit1 = splitArray($array_1);
$arraySplit2 = splitArray($array_2);
foreach ($arraySplit1 as $key1 => $value1) {
if (array_key_exists($key1, $arraySplit2)) {
$arraySplit1[$key1] = $arraySplit2[$key1];
}
}
print_r($arraySplit1);
See it working here:
http://3v4l.org/2BrVI
$array_1=array("1a-dogs","2a-cats","3a-birds","4a-people");
$array_2=array("4a-walking","2a-cats");
function merge_array($arr1, $arr2) {
$arr_tmp1 = array();
foreach($arr1 as $val) {
list($key, $val) = explode('-', $val);
$arr_tmp1[$key] = $val;
}
foreach($arr2 as $val) {
list($key, $val) = explode('-', $val);
if(array_key_exists($key, $arr_tmp1))
$arr_tmp1[$key] = $val;
}
return $arr_tmp1;
}
$result = merge_array($array_1, $array_2);
echo '<pre>';
print_r($result);
echo '</pre>';
This short code works properly, you'll get this result:
Array
(
[1a] => dogs
[2a] => cats
[3a] => birds
[4a] => walking
)

array_flip of a key value for letter and numbers

I have an array like this
array(123=>'c', 125=>'b', 139=>'a', 124=>'c', 135=>'c', 159=>'b');
and I want to flip the key/values so that duplicate values become an index for an array.
array(
'a'=>array(139),
'b'=>array(125, 159),
'c'=>array(123, 124, 135)
);
However, array_flip seems to overwrite the keys and array_chunk only splits it based on number values.
Any suggestions?
I think it's going to need you to loop over the array manually. It really shouldn't be hard though...
$flippedArray = array();
foreach( $arrayToFlip as $key => $value ) {
if ( !array_key_exists( $value, $flippedArray ) {
$flippedArray[ $value ] = array();
}
$flippedArray[ $value ][] = $key;
}
function array_flop($array) {
foreach($array as $k => $v) {
$result[$v][] = $k;
}
return array_reverse($result);
}

PHP Multidimensional Array push and loop

I'm having some trouble understanding the coding in PHP, when it comes to multidimensional arrays and how to push.
The idea is to push a "Attribute" and a "Attribute value"
I have tried the formula below
$i = 0;
$array = array();
foreach($node as $a)
{
$strAtt = $node->PROP[$i]->attributes();
$strVal = $node->PROP[$i]->PVAL;
$output = $output.$strAtt." : ".$strVal."<BR>";
$array[] = ($strAtt => $strVal);
The $array[] = ($strAtt => $strVal); doesnt give me much success.
I have tried array_push($array, $strAtt => $strVal) - no luck..
As an extra questions, how do I loop trough the array and print me multidimensional values ?.
NEW CODE
while ($z->name === 'RECORD')
{
$node = new SimpleXMLElement($z->readOuterXML());
$Print = FALSE;
$output = "";
$i = 0;
foreach($node as $a)
{
$strAtt = $node->PROP[$i]->attributes();
$strVal = $node->PROP[$i]->PVAL;
$output = $output.$strAtt." : ".$strVal."<BR>";
$array[$strAtt] = $strVal;
if(($i == 6) && ($node->PROP[$i]->PVAL == $ProductLookup))
{
$Print = TRUE;
$Product = $node->PROP[$i]->PVAL;
}
$i++;
}
if($Print == TRUE) {
echo $output;
echo "Product : ".$Product."<br>";
var_dump($array);
}
//print_r($array);
$print = FALSE;
// go to next <product />
$z->next('RECORD');
}
New code added. For some reason my $array is totally empty when i dump it, although my $Output is full of text ?
It sounds like you are wanting an "associative" array and not necessarily a multi-dimensional array. For associative arrays you don't use array_push. Just do this:
$array[$strAtt] = $strVal;
Then to loop the array just do this:
foreach ($array as $key => $value) {
echo "$key = $value\n";
}
Go through array in php , you will understand how array works in php.
Besides if you want to add an element to a multidimensional array you can achieve like this :
$node = array ("key1"=> array (a,b) , "key2"=> array (c,d));
$array = array();
foreach ($node as $key=>$value) {
$array [$key] = $value;
}
This will be the resulting $array after the loop :
array (
"key1"=> array (
a,b
) ,
"key2"=>
array (c,d)
)
Hope that helps , happy coding :)

PHP Dynamically adding dimensions to an array using for loop

Here is my dilemma and thank you in advance!
I am trying to create a variable variable or something of the sort for a dynamic associative array and having a hell of a time figuring out how to do this. I am creating a file explorer so I am using the directories as the keys in the array.
Example:
I need to get this so I can assign it values
$dir_list['root']['folder1']['folder2'] = value;
so I was thinking of doing something along these lines...
if ( $handle2 = #opendir( $theDir.'/'.$file ))
{
$tmp_dir_url = explode($theDir);
for ( $k = 1; $k < sizeof ( $tmp_dir_url ); $k++ )
{
$dir_list [ $dir_array [ sizeof ( $dir_array ) - 1 ] ][$tmp_dir_url[$k]]
}
this is where I get stuck, I need to dynamically append a new dimension to the array durring each iteration through the for loop...but i have NO CLUE how
I would use a recursive approach like this:
function read_dir_recursive( $dir ) {
$results = array( 'subdirs' => array(), 'files' => array() );
foreach( scandir( $dir ) as $item ) {
// skip . & ..
if ( preg_match( '/^\.\.?$/', $item ) )
continue;
$full = "$dir/$item";
if ( is_dir( $full ) )
$results['subdirs'][$item] = scan_dir_recursive( $full );
else
$results['files'][] = $item;
}
}
The code is untested as I have no PHP here to try it out.
Cheers,haggi
You can freely put an array into array cell, effectively adding 1 dimension for necessary directories only.
I.e.
$a['x'] = 'text';
$a['y'] = new array('q', 'w');
print($a['x']);
print($a['y']['q']);
How about this? This will stack array values into multiple dimensions.
$keys = array(
'year',
'make',
'model',
'submodel',
);
$array = array();
print_r(array_concatenate($array, $keys));
function array_concatenate($array, $keys){
if(count($keys) === 0){
return $array;
}
$key = array_shift($keys);
$array[$key] = array();
$array[$key] = array_concatenate($array[$key], $keys);
return $array;
}
In my case, I knew what i wanted $keys to contain. I used it to take the place of:
if(isset($array[$key0]) && isset($array[$key0][$key1] && isset($array[$key0][$key1][$key2])){
// do this
}
Cheers.

Categories