I have 10 sets of 3 values. At each point, I will only know 1 of the values and need to retrieve the other 2 values. For example, I know what id_a2 is, how do I use that to get id_a1 and id_a3?
id_a1, id_a2, id_a3
id_b1, id_b2, id_b3
id_c1, id_c2, id_c3...
Store it in a multi-dimentional array, then loop through it:
$data = array(
array('id_a1', 'id_a2', 'id_a3'),
array('id_b1', 'id_b2', 'id_b3'),
array('id_c1', 'id_c2', 'id_c3')
);
find_siblings('id_b2', $data); // returns: array('id_b1', 'id_b3')
function find_siblings ( $needle, $haystack )
{
foreach ( $haystack as $array )
{
if ( in_array($needle, $array) )
{
$out = array();
foreach ( $array as $value )
{
if ( $value != $needle ) $out[] = $value;
}
return $out;
}
}
}
See it here in action: http://viper-7.com/VPVTnU
Related
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
I have an array like below
Array
(
[0] => country-indonesia
[1] => country-myanmar
[2] => access-is_airport
[3] => heritage-is_seagypsy
)
From that array I want to make separate array only for [country] ,[access], [heritage]
So for that I have to check array value by text before '-'. I am not sure how to do it. so i can't apply code here. I just have the array in PHP
A modified answer, if you want to get the specific types only.
<?php
$arr = [
'country-indonesia',
'country-myanmar',
'access-is_airport',
'heritage-is_seagypsy',
];
$new_array = [];
$types = ['country', 'heritage', 'access'];
foreach ($arr as $element) {
$fac = explode('-', $element);
foreach ($types as $type) {
if ($fac[0] === $type) {
$new_array[$type][] = $fac[1];
}
}
}
$country = $new_array['country'];
$access = $new_array['access'];
$heritage = $new_array['heritage'];
var_dump($new_array);
A simple and easy solution in 3 lines of code using array_walk
<?php
$arr = [
'country-indonesia',
'country-myanmar',
'access-is_airport',
'heritage-is_seagypsy',
];
$new_array = [];
array_walk($arr, function($item) use (&$new_array){
//if(false === strpos($item, '-')) return;
list($key,$value) = explode('-', $item, 2);
$new_array[$key][] = $value;
});
print_r($new_array);
Gives this output:
Array
(
[country] => Array
(
[0] => indonesia
[1] => myanmar
)
[access] => Array
(
[0] => is_airport
)
[heritage] => Array
(
[0] => is_seagypsy
)
)
If you don't want empty and duplicate entries:
<?php
$arr = [
'country-indonesia',
'country-myanmar',
'access-is_airport',
'heritage-is_seagypsy',
];
$new_array = [];
array_walk($arr, function($item) use (&$new_array){
if(false === strpos($item, '-')) return;
list($key,$value) = explode('-', $item, 2);
if(empty($value) || array_key_exists($key, $new_array) && in_array($value, $new_array[$key])) return;
$new_array[$key][] = $value;
});
print_r($new_array);
you can do it by using explode and in_array functions
<?php
$arr = ["country-indonesia","country-myanmar","access-is_airport","heritage-is_seagypsy"];
$newArr = array();
foreach($arr as $k=> $val){
$valArr = explode("-", $val);
if(!in_array($valArr[0], $newArr)){
$newArr[] = $valArr[0];
}
}
print_r($newArr);
?>
live demo
You need PHP's strpos() function.
Just loop through every element of the array and try something like:
if( strpos($array[$i], "heritage") != false )
{
// Found heritage, do something with it
}
(Rough example written from my cellphone while feeding baby, may have typos but it's the basics of what you need)
Read further here: http://php.net/manual/en/function.strpos.php
//first lets set a variable equal to our array for ease in working with i.e
// also create a new empty array to hold our filtered values
$countryArray = array();
$accessArray = array();
$heritageArray = array();
$oldArray = Array(country-indonesia, country-myanmar, access-is_airport, heritage-is_seagypsy);
//Next loop through our array i.e
for($x = 0; $x < count($oldArray); $x++){
// now filter through the array contents
$currentValue = $oldArray[$x];
// check whether the current index has any of the strings in it [country] ,[access], [heritage] using the method : strpos()
if(strpos($currentValue,'country')){
//if this particular value contains the keyword push it into our new country array //using the array_push() function.
array_push($countryArray,$currentValue);
}elseif(strpos($currentValue,'access')){
// else check for the access string in our current value
// once it's found the current value will be pushed to the $accessArray
array_push($accessArray,$currentValue);
}elseif(strpos($currentValue,'heritage')){
// check for the last string value i.e access. If found this too should be pushed to //the new heritage array i.e
array_push($heritageArray,$currentValue);
}else{
// do nothing
}
}
//I believe that should work: cheers hope
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
I have q question: what is the easiest way to create multi-dimensional array in php dynamically?
Here a static version:
$tab['k1']['k2']['k3'] = 'value';
I would like to avoid eval()
I'm not successful with variable variable ($$)
so I'm trying to develop a function fun with such interface:
$tab = fun( $tab, array( 'k1', 'k2', 'k3' ), 'value' );
Do you have a solution? What is the simplest way?
regards,
Annie
There are a number of ways to achieve this, but here is one which uses PHP's ability to have N arguments passed to a function. This gives you the flexibility of creating an array with a depth of 3, or 2, or 7 or whatever.
// pass $value as first param -- params 2 - N define the multi array
function MakeMultiArray()
{
$args = func_get_args();
$output = array();
if (count($args) == 1)
$output[] = $args[0]; // just the value
else if (count($args) > 1)
{
$output = $args[0];
// loop the args from the end to the front to make the array
for ($i = count($args)-1; $i >= 1; $i--)
{
$output = array($args[$i] => $output);
}
}
return $output;
}
Here's how it would work:
$array = MakeMultiArray('value', 'k1', 'k2', 'k3');
And will produce this:
Array
(
[k1] => Array
(
[k2] => Array
(
[k3] => value
)
)
)
Following function will work for any number of keys.
function fun($keys, $value) {
// If not keys array found then return false
if (empty($keys)) return false;
// If only one key then
if (count($keys) == 1) {
$result[$keys[0]] = $value;
return $result;
}
// prepare initial array with first key
$result[array_shift($keys)] = '';
// now $keys = ['key2', 'key3']
// get last key of array
$last_key = end($keys);
foreach($keys as $key) {
$val = $key == $last_key ? $value : '';
array_walk_recursive($result, function(&$item, $k) use ($key, $val) {
$item[$key] = $val;
});
}
return $result;
}
This should work if $tab always has 3 indices:
function func(&$name, $indices, $value)
{
$name[$indices[0]][$indices[1]][$indices[2]] = $value;
};
func($tab, array( 'k1', 'k2', 'k3' ), 'value' );
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);
}