I have 3 arrays like this :
$first = array(
[0] => 13
[1] => 66
[2] => 15
)
$second = array
(
[0] => append
[1] => prepend
[2] => append
)
$third = array
(
[0] => 2
[1] => 4
[2] => 1
)
Now I want to combine these 3 array and create new SINGLE array like this :
I want to get value from each array and combine it into one.
$new_array = array(
[0] = array (
'page'=>13,
'position'=>'append'
'priority'=>'2'
)
[1] = array (
'page'=>66,
'position'=>'prepend'
'priority'=>'4'
)
[2] = array (
'page'=>15,
'position'=>'append'
'priority'=>'1'
)
)
How to do this ?
You can use array_map() to traverse multiple arrays(of the same length) and build a new array from them, item by item:
$first = array(13, 66, 15);
$second = array('append', 'prepend', 'append');
$third = array(2, 4, 1);
print_r(
array_map(
function($page, $position, $priority) {
return compact('page', 'position', 'priority');
},
$first,
$second,
$third
)
);
Though in this case with a trivial structure foreach() might be an alternative.
Edit: Version 2. Some might argue that this is worse because of readability and hence code maintainability. Thanks to AbraCadaver
$keys = ['page', 'position', 'priority'];
// Note: The order in $keys and array_map() arguments must be the same
// On the other hand you only need to type the keys once and it's easy
// to change the number of arguments :)
print_r(
array_map(
function(...$args) use ($keys) {
return array_combine($keys, $args);
},
$first,
$second,
$third
)
);
Edit: Version 3. Using slightly more modern PHP (7.4) with arrow functions:
print_r(
array_map(
fn(...$args) => array_combine($keys, $args),
$first,
$second,
$third
)
);
Just map each element of each array and return an array with the keys:
$result = array_map(function($f, $s, $t) {
return ['page'=>$f, 'position'=>$s, 'priority'=>$t];
}, $first, $second, $third);
Or define the keys outside of the function and combine with each element:
$keys = ['page', 'position', 'priority'];
$result = array_map(function($f, $s, $t) use($keys) {
return array_combine($keys, [$f, $s, $t]);
}, $first, $second, $third);
If you have same column, you can do it like this
$first = [13,66,15];
$second = ['append','prepend','append'];
$third = [2,4,1];
foreach($first as $v => $i){
$new_array[] = [
'page' => $i,
'position' => $second[$v],
'priority' => $third[$v],
];
}
print_r($new_array);
this is the result
Related
I have an array that looks like this:
array
(
[name] => name
[description] => description here
[first] => Array
(
[0] => weight
[1] => height
)
[second] => Array
(
[0] => 20 kg
[1] => 50 cm
)
[company_id] => 1
[category_id] => 7
)
what function will allow me to combine these into something that looks like the following?
array
(
[together]
(
[0] => weight 20kg
[1] => height 50cm
)
)
Update
For that current array you need to use the loop.
$first = $second = array();
foreach($yourArray as $key => $array) {
if(in_array($key, array('first', 'second')) {
$first[] = $array[0];
$second[] = $array[1];
}
}
$final['together'] = array($first, $second);
According to the first array
You can try this -
$new = array(
'together' => array(
implode(' ', array_column($yourArray, 0)), // This would take out all the values in the sub arrays with index 0 and implode them with a blank space
implode(' ', array_column($yourArray, 1)), // Same as above with index 1
)
);
array_column is supported PHP >= 5.5
Or you can try -
$first = $second = array();
foreach($yourArray as $array) {
$first[] = $array[0];
$second[] = $array[1];
}
$final['together'] = array($first, $second);
you also can try array_map as below
function merge($first,$second)
{
return $first ." ".$second;
}
$combine = array_map('merge', $yourArray[0],$yourArray[1]);
I have an array in the following format:
Array (
[0] => Array
(
[option_id] => 10820
[option_name] => PREFIX_FIRST_OPT_KEY
[option_value] => FIRST_OPT_VALUE
[autoload] => yes
)
[1] => Array
(
[option_id] => 10821
[option_name] => PREFIX_SECOND_OPT_KEY
[option_value] => SECOND_OPT_VALUE
[autoload] => yes
)
[2] => Array
(
[option_id] => 10824
[option_name] => PREFIX_THIRD_OPT_KEY
[option_value] => SECOND_OPT_VALUE
[autoload] => yes
)
)
What is the appropriate function to use to get a one dimensional associative array with the following structure?
Array (
[FIRST_OPT_KEY] => FIRST_OPT_VALUE
[SECOND_OPT_KEY] => SECOND_OPT_VALUE
[THIRD_OPT_KEY] => THIRD_OPT_VALUE
)
I only want to keep the indicated values as key value pairs in the new array and ignore the rest - PREFIX_ is fixed length.
What I am doing right now:
foreach ( $the_original_array as $key => $value ) {
$new_key = substr($the_original_array[$key]['option_name'], 7);
$option_value = $the_original_array[$key]['option_value'];
$new_array[$new_key] = $option_value;
}
but I feel there ought to be a cleaner/more efficient way of accomplishing this
If you have PHP >= 5.5:
To extract values:
$result = array_column($array, 'option_value', 'option_name');
Then to remove prefix:
$result = array_combine(
array_map(
function($k){
return str_replace('PREFIX_', '', $k);
},
array_keys($result)
), $result
);
A way of simulating array_column() if you aren't running PHP 5.5+
$newArray = array_combine(
array_map(
function($value) {
return substr($value['option_name'], 7);
},
$the_original_array
),
array_map(
function($value) {
return $value['option_value'];
},
$the_original_array
)
);
The accepted answer is valid, but it causes the data to be iterated over multiple times. Assuming PHP < 5.5.0, using array_reduce will loop over the data only once, and return the same result:
$iterator = function($result, $record) {
$key = substr($record['option_name'], 7);
$result[$key] = $record['option_value'];
return $result;
};
$newArray = array_reduce($original, $iterator, array());
I would use array_column but for PHP < 5.5.0 what you have is about the best you can do, but you can use the $value that is generated by the foreach:
foreach ( $the_original_array as $value ) {
$new_key = substr($value['option_name'], 7);
$option_value = $value['option_value'];
$new_array[$new_key] = $option_value;
}
I think than foreach is good like:
$new = array();
foreach ($original_array as $item) {
$index = str_replace('PREFIX_', '', $item['option_name']);
$new[$index] = $item['option_value'];
}
I need to divide an array into two arrays.
One array will contain all positive values (and zeros), the other all negative values.
Example array:
$ts = [7,-10,13,8,0,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7];
Negatives result array:
[-10,-7.2,-12,-3.7,-9.6,-1.7,-6.2];
Non-negatives result array:
[7,13,8,0,4,3.5,6.5,7];
Without using any array functions..
Pretty straightforward. Just loop through the array and check if the number is less than 0, if so , push it in the negative array else push it in the positive array.
<?php
$ts=array(7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7);
$pos_arr=array(); $neg_arr=array();
foreach($ts as $val)
{
($val<0) ? $neg_arr[]=$val : $pos_arr[]=$val;
}
print_r($pos_arr);
print_r($neg_arr);
OUTPUT :
Array
(
[0] => 7
[1] => 13
[2] => 8
[3] => 4
[4] => 3.5
[5] => 6.5
[6] => 7
)
Array
(
[0] => -10
[1] => -7.2
[2] => -12
[3] => -3.7
[4] => -9.6
[5] => -1.7
[6] => -6.2
)
You can use array_filter function,
$positive = array_filter($ts, function ($v) {
return $v > 0;
});
$negative = array_filter($ts, function ($v) {
return $v < 0;
});
Note: This will skip values with 0, or you can just change condition to >=0 in positive numbers filter to considered in positive group.
DEMO.
The most elegant is to use phps array_filter() function:
<?php
$ts = [ 7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7 ];
print_r( array_filter( $ts, function( $val ) { return (0>$val); } ) );
print_r( array_filter( $ts, function( $val ) { return ! (0>$val); } ) );
?>
If you are still using an older php version you need some longer implementation:
<?php
$ts = array( 7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7 );
print_r( array_filter( $ts, create_function( '$val', 'return (0>$val);' ) ) );
print_r( array_filter( $ts, create_function( '$val', 'return ! (0>$val);' ) ) );
?>
Food for thought, you could write a generic function that splits an array based on a boolean result:
// splits an array based on the return value of the given function
// - add to the first array if the result was 'true'
// - add to the second array if the result was 'false'
function array_split(array $arr, callable $fn)
{
$a = $b = [];
foreach ($arr as $key => $value) {
if ($fn($value, $key)) {
$a[$key] = $value;
} else {
$b[$key] = $value;
}
}
return [$a, $b];
}
list($positive, $negative) = array_split($ts, function($item) {
return $item >= 0;
});
print_r($positive);
print_r($negative);
Demo
Rather than declaring two arrays, I recommend declaring one array with two subarrays. You can either give the subarrays an index of 0 or 1 depending on the conditional evaluation with zero, or you can go a little farther by declaring a lookup array to replace the integer key with an expressive word.
Regardless of if you choose to create one array or two arrays, you should only make one loop over the input array. Making two loops or by calling array_filter() twice is needlessly inefficient.
Code: (Demo)
$ts = [7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7];
const KEY_NAMES = [0 => 'negative', 1 => 'non-negatuve'];
$result = [];
foreach ($ts as $v) {
$result[KEY_NAMES[$v >= 0]][] = $v;
}
var_export($result);
Output:
array (
'non-negatuve' =>
array (
0 => 7,
1 => 13,
2 => 8,
3 => 4,
4 => 3.5,
5 => 6.5,
6 => 7,
),
'negative' =>
array (
0 => -10,
1 => -7.2,
2 => -12,
3 => -3.7,
4 => -9.6,
5 => -1.7,
6 => -6.2,
),
)
I have two multidimensional arrays that I need to determine the delta for each value. I know the array_diff function only returns the difference in keys. Is there a functon that will determine the delta for each set of values assuming the two arrays contain the same set of keys?
Example:
array_1(test1 => Array([key1] => 100, [key2] => 200 ) )
array_2(test1 => Array([key1] => 105, [key2] => 195 ) )
I would expect something like:
array_3(test1 => Array([key1] => 5, [key2] => -5 ) )
Are there any PHP methods to do this or am I on my own?
Answers here suggested using foreach loop but I think creating anonymous function will be easier:
<?php
$count_delta = create_function('$a,$b', 'return $a - $b;');
$arr1 = array(100, 200);
$arr2 = array(20, 180);
$delta = array_map($count_delta, $arr1, $arr2);
var_dump($delta);
Output will be:
array
0 => int 80
1 => int 20
$delta = array();
foreach( $array1 as $k=>$v )
{
if( array_key_exists( $k, $array2 )
{
// preserve the key
$delta[$k] = $array1[$k] - $array2[$k];
// or don't
$delta[] = $array1[$k] - $array2[$k];
}
}
print_r($delta);
There is no built-in function for that, but you can use this.
function delta_array($a, $b) {
if (sizeof($a) != sizeof($b))
return false;
$arr = array();
for ($i=0; $i < $c = sizeof($a); $i++)
$arr[] = $b[$i] - $a[$i];
return $arr;
}
$arr1 = array(100,200);
$arr2 = array(105,195);
$delta = delta_array($arr1, $arr2);
print_r($delta);
The above will return
Array
(
[0] => -5
[1] => 5
)
I have a few associative arrays that I need to merge together based on there key.
so:
array1:
[person1] => tony
[person2] => sandra
array2:
[person1] => london
[person2] => paris
needs to be :
array 3
[person1] => tony , london
[person2] => sandra , paris
The issue I'm having though is that the key could be any value , so it could be 'person1' or it could be 'hairyOtter' and the array is of varaible size.
Assuming, that every is not multi-dimensional
$merged = array_merge_recursive($array1, $array2);
foreach ($merged as &$entry) {
if (is_array($entry)) {
$entry = implode(', ', $entry);
}
}
The idea is, that array_merge_recursive() creates a new array, if it find two values with the same key. Everything else stays untouched.
I'm sure there are more efficient ways to accomplish this, but for now, this works:
<?php
function combine( $keys, $first, $second ) {
$args = func_get_args( );
$keys = array_shift( $args );
$arrays = $args;
$result = array( );
foreach( $keys as $key ) {
foreach( $arrays as $array ) {
if( isset( $array[$key] ) ) {
$result[$key][] = $array[$key];
}
}
}
return $result;
}
$first = array(
'person1' => 'tony',
'person2' => 'sandra'
);
$second = array(
'person1' => 'london',
'person2' => 'paris'
);
/**
* To make sure you get *every* key out of both arrays.
*/
$keys = array_unique( array_merge( array_keys( $first ), array_keys( $second ) ) );
$combined = combine( $keys, $first, $second );
var_dump( $combined );
Two loops should do it. Iterate over each of array1 and array2, initialising array3's keys as you go to an array, and pushing into that array. Here's the first loop
$array3 = array();
foreach (array_keys($array1) as $key) {
if(!array_key_exists($key, $array3)) {
$array3[$key] = array();
}
array_push($array3[$key], $array1[$key]);
}
$array1 = array('a' => 1, 'b' => 2);
$array2 = array('a' => 3, 'b' => 4, 'c' => 5);
foreach ($array1 as $k => $v) {
$tArray[$k][] = $v;
}
foreach ($array2 as $k => $v) {
$tArray[$k][] = $v;
}
foreach ($tArray as $k => $v) {
$tArray[$k] = implode(',',$tArray[$k]);
}
I would create a multi-dimensional array instead, unless there is a specific reason you can't use one. This way, you would have an array that looks like:
Array
(
[Person1] => Array
(
[Name] => Tony
[City] => London
)
[Person2] => Array
(
[Name] => Sandra
[City] => Paris
)
)