I want to change the order from:
$array = array(
"a" => "bar",
"b" => "foo",
"c" => "bar",
"d" => "foo",
"e" => "bar",
"f" => "foo",
"g" => "bar",
"h" => "foo",
"i" => "bar",
"j" => "foo"
);
To:
$array = array(
"a" => "bar", "f"=> "foo",
"b" => "foo", "g"=> "bar",
"c" => "bar", "h"=> "foo",
"d" => "foo", "i"=> "bar",
"e" => "bar", "j"=> "foo"
);
The point of this is that I want to fill a table with the items in the array:
The array should not be sorted like this:
<table>
<tr><td>Item 1</td><td>Item 2</td></tr>
<tr><td>Item 3</td><td>Item 4</td></tr>
</table>
But like this:
<table>
<tr><td>Item 1</td><td>Item 3</td></tr>
<tr><td>Item 2</td><td>Item 4</td></tr>
</table>
Thanks
There is no need to rearrange the original array. Just split it up in two pairs using array_chunk, and loop through them when building the html.
$array = array(....);
$size = ceil(count($array) / 2);
list($left, $right) = array_chunk($array, $size, true);
echo '<table>';
while (count($left) > 0) {
echo '<tr>';
echo '<td>', key($left), ': ', array_shift($left), '</td>';
echo '<td>', key($right), ': ', array_shift($right), '</td>';
echo '</tr>';
}
echo '</table>';
I assume that it does not mater whether the key is an string or a integer.
$array = array(
4 => 'd',
2 => 'b',
3 => 'c',
6 => 'f',
5 => 'e',
1 => 'a'
);
$x = floor(count( $array ) / 2);
for( $i=1; $i <= $x; $i++ )
{
$array2[ $i ] = $array[ $i ];
$array2[ $i + $x ] = $array[ $i + $x ];
}
will output:
$Array2
(
[1] => a, [4] => d,
[2] => b, [5] => e,
[3] => c, [6] => f
)
JB
Related
I'm trying to divide arrays equally from two sets of arrays
For example:
$arr1 = [a,b,c,d,e];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
What I have tried:
$arr1 = [a,b,c,d,e];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
$arrRes = [];
$key = 0;
for($i=0;$i<count($arr1);$i++){
$arrRes[$arr1[$key]][] = $arr2[$i];
$key++;
}
$key2 = 0;
for($k=0;$k<count($arr1);$k++){
$arrRes[$arr1[$key2]][] = $arr2[$key];
$key++;
$key2++;
if ($key == count($arr2)) {
break;
}
}
I expect to get the output:
[
"a" => [1,6,11],
"b" => [2,7,12],
"c" => [3,8,13],
"d" => [4,9],
"e" => [5,10]
]
but the actual output I get is :
[
"a" => [1,6],
"b" => [2,7],
"c" => [3,8],
"d" => [4,9],
"e" => [5,10]
]
Another way with just using 1 loop (comments in code)...
$arr1 = ['a','b','c','d','e'];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
// Create output array from the keys in $arr1 and an empty array
$arrRes = array_fill_keys($arr1, []);
$outElements = count($arr1);
// Loop over numbers
foreach ( $arr2 as $item => $value ) {
// Add the value to the index based on the current
// index and the corresponding array in $arr1.
// Using $item%$outElements rolls the index over
$arrRes[$arr1[$item%$outElements]][] = $value;
}
print_r($arrRes);
Output...
Array
(
[a] => Array
(
[0] => 1
[1] => 6
[2] => 11
)
[b] => Array
(
[0] => 2
[1] => 7
[2] => 12
)
[c] => Array
(
[0] => 3
[1] => 8
[2] => 13
)
[d] => Array
(
[0] => 4
[1] => 9
)
[e] => Array
(
[0] => 5
[1] => 10
)
)
The code snippet bellow does exactly what you want. It calculates the max length of the resulting inner arrays (which in your case is 13/5+1=3) by dividing the length of the 2nd array with the length of the 1st array. Then, for each element in the 1st array, it goes from 0 to the max length and adds the element from the 2nd array at that position to the resulting array. In the case that the position is out of bounds, the inner for loop is exited.
$arr1 = ['a', 'b', 'c', 'd', 'e'];
$arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
$arrRes = [];
// create an empty result array of arrays
foreach($arr1 as $key){
// the keys are the values from the 1st array
$arrRes[$key] = [];
}
$maxLength = intval(count($arr2) / count($arr1)) + 1;
for($i = 0; $i < count($arr1); ++$i) {
for($j = 0; $j < $maxLength; ++$j) {
$pos = $j * count($arr1) + $i;
if($pos >= count($arr2)) {
break;
}
$arrRes[$arr1[$i]][] = $arr2[$pos];
}
}
The above code produces:
[
"a" => [1,6,11],
"b" => [2,7,12],
"c" => [3,8,13],
"d" => [4,9],
"e" => [5,10]
]
And if you want a result like this:
[
"a" => [1,2,3],
"b" => [4,5,6],
"c" => [7,8,9],
"d" => [10,11],
"e" => [12,13]
]
... then this code will do this (the main difference is in getting the position and determining when to break the inner loop):
$arr1 = ['a', 'b', 'c', 'd', 'e'];
$arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
$arrRes = [];
foreach($arr1 as $key){
$arrRes[$key] = [];
}
$maxLength = intval(count($arr2) / count($arr1)) + 1;
$pos = 0;
for($i = 0; $i < count($arr1); ++$i) {
$arraysLeftAfter = count($arr1) - $i - 1;
for($j = 0; $j < $maxLength && $pos < count($arr2); ++$j) {
if($arraysLeftAfter > 0) {
$elCountAfter = count($arr2) - $pos - 1;
$myLengthAfter = ($j + 1);
$maxLengthAfter = floor(($elCountAfter / $arraysLeftAfter) + 1);
if($myLengthAfter > $maxLengthAfter) {
break;
}
}
$arrRes[$arr1[$i]][] = $arr2[$pos++];
}
}
A different approach:
$arr1 = ['a','b','c','d','e'];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
$i =0;
$res = array_fill_keys($arr1, []);
while(isset($arr2[$i])){
foreach($res as $k=>&$v){
if(!isset($arr2[$i])) break;
$v[] = $arr2[$i];
$i++;
}
}
print_r($res);
Result:
Array
(
[a] => Array
(
[0] => 1
[1] => 6
[2] => 11
)
[b] => Array
(
[0] => 2
[1] => 7
[2] => 12
)
[c] => Array
(
[0] => 3
[1] => 8
[2] => 13
)
[d] => Array
(
[0] => 4
[1] => 9
)
[e] => Array
(
[0] => 5
[1] => 10
)
)
i have a array and how can i cover it to string fastest ?
Array
(
[1] => 1,
[2] => 8,
[3] => 10,
[4] => 16,
)
I need cover it to this string $var = (1,8,10,16)
Just implode it:
$var = '(' . implode(',', $data) . ');
Live example: https://3v4l.org/9bsZF
you can use simple implode function for that .
$arr = array(
"1" => 1,
"2" => 8,
"3" => 10,
"4" => 16
);
echo implode($arr, ",");
output : 1,8,10,16
OR
foreach ($arr as $value) {
echo $value .", ";
}
Output : 1, 8, 10, 16,
A have a php array
$arr = array(
1 => "a",
2 => "b",
4 => "c",
8 => "d",
16 => "e",
32 => "f"
);
and a binary number
$filter=101101
I want to filter the array and keep only the keys where the respective value on binary is 1
For this example I would have:
$arr = array(
1 => "a",
4 => "c",
8 => "d",
32 => "f"
);
Or for
$filter=110001
to get
$arr = array(
1 => "a",
2 => "b",
32 => "f"
);
Assuming that the length of $filter is always the same as the number of array elements:
$filter_arr = str_split($filter);
$new_arr = array();
$i = 0;
foreach ($arr as $key => $val) {
if ($filter_arr[$i] == 1) {
$new_arr[$key] = $val;
}
$i++;
}
Using your given array, and filter equal to 101101, $new_arr will equal:
Array
(
[1] => a
[4] => c
[8] => d
[32] => f
)
See demo
This should work for you:
<?php
$arr = array(
1 => "a",
2 => "b",
4 => "c",
8 => "d",
16 => "e",
32 => "f"
);
$filter=110001;
$filerValue = str_split($filter);
$count = 0;
foreach($arr as $k => $v) {
if($filerValue[$count] == 0)
unset($arr[$k]);
$count++;
}
var_dump($arr);
?>
Output:
array(3) {
[1]=>
string(1) "a"
[2]=>
string(1) "b"
[32]=>
string(1) "f"
}
Example:
$arr1 = array('a' => "1", 'b' => "2", 'c' => "3", 'z' => "4");
$arr2 = array('a' => "9", 'b' => "8", 'c' => "7", 'd' => "6", 'e' => "5");
Output:
$result = array(
'a' => array( 'f1' => "1", 'f2' => "9"),
'b' => array( 'f1' => "2", 'f2' => "8"),
'c' => array( 'f1' => "3", 'f2' => "7"),
'd' => array( 'f1' => "0", 'f2' => "6"),
'e' => array( 'f1' => "0", 'f2' => "5"),
'z' => array( 'f1' => "4", 'f2' => "0"),
);
The size of $arr1 can be '>', '<' or '=' size of $arr2
I think this it,
$arr1 = array('a' => "1", 'b' => "2", 'c' => "3", 'z' => "4");
$arr2 = array('a' => "9", 'b' => "8", 'c' => "7", 'd' => "6", 'e' => "5");
foreach($arr1 as $key => $value){
$a[$key]['f1'] = $value;
}
foreach($arr2 as $key => $value){
$b[$key]['f2'] = $value;
}
$c = array_merge_recursive($a, $b);
foreach($c as $key => $value){
$result[$key]['f1'] = (array_key_exists('f1', $value)) ? $value['f1']: 0;
$result[$key]['f2'] = (array_key_exists('f2', $value)) ? $value['f2']: 0;
}
echo "<pre>".print_r ($result, true);
the output:
Array
(
[a] => Array
(
[f1] => 1
[f2] => 9
)
[b] => Array
(
[f1] => 2
[f2] => 8
)
[c] => Array
(
[f1] => 3
[f2] => 7
)
[z] => Array
(
[f1] => 4
[f2] => 0
)
[d] => Array
(
[f1] => 0
[f2] => 6
)
[e] => Array
(
[f1] => 0
[f2] => 5
)
)
array_merge_recursive() should work: http://php.net/manual/en/function.array-merge-recursive.php
otherwise it's simple enough wo implement in a few lines: (Unless you really need the "fn" indices.)
function my_merge(){
$result = array();
foreach(func_get_args() as $a)
foreach($a as $index => $value)
$result[$index][] = $value;
}
Try this:
$keys = array_unique(array_merge(array_keys($arr1), array_keys($arr2)));
$values = array_map(function($key) use ($arr1, $arr2) {
return array('f1' => isset($arr1[$key]) ? $arr1[$key] : "0",
'f2' => isset($arr2[$key]) ? $arr2[$key] : "0"); }
, $keys);
$result = array_combine($keys, $values);
var_dump($result);
Some explanation:
At first get an array $keys of all unique keys of both arrays.
Then for each key the corresponding array of values is then generated.
At last the array of keys and the array of values are combined.
But this does currently only work with two arrays.
Edit Here’s one that works with an arbitrary number of arrays:
$arrays = array($arr1, $arr2);
$keys = array_unique(call_user_func_array('array_merge', array_map('array_keys', $arrays)));
$values = array_map(function($key) use ($arrays) {
return array_combine(array_map(function($key) {
return 'f'.($key+1);
}, array_keys($arrays)),
array_map(function($array) use ($key) {
return isset($array[$key]) ? $array[$key] : "0";
}, $arrays));
}, $keys);
$result = array_combine($keys, $values);
var_dump($result);
Some explanation:
Put all arrays in an array $arrays.
For each array in $arrays, call array_keys on it to get the keys, merge these arrays and get an array $keys of all unique keys.
For each key in $keys, check if the key exists in the array of arrays $arrays.
Combine the keys and values.
$arr1 = array('a' => "1", 'b' => "2", 'c' => "3", 'z' => "4");
$arr2 = array('a' => "9", 'b' => "8", 'c' => "7", 'd' => "6", 'e' => "5");
function combineArray($arr1, $arr2) {
if (is_array($arr1) && is_array($arr2)) {
$rArr = array();
$steps = max ( count($arr1),count($arr2));
$ak1 = array_keys($arr1);
$ak2 = array_keys($arr2);
for ($i=0;$i<$steps;$i++) {
if (!isset($rArr[$i])) $rArr[$i]=array();
$rArr[$i]['f1'] = (isset($arr1[$ak1[$i]])) ? $arr1[$ak1[$i]]: '0';
$rArr[$i]['f2'] = (isset($arr2[$ak2[$i]])) ? $arr2[$ak2[$i]]: '0';
}
return $rArr;
}else {
return false;
}
}
echo "<pre>".print_r (combineArray($arr1, $arr2),true);
might work :)
Run through the first array, store the f1 values from the array and set the default 0 for all f2 values.
Run through the second array, store the f2 values from the array and only set the default 0 for the respective f1 value if it is not already declared.
Use ksort() if desired to alphabetize the first level keys.
Code: (Demo)
$array1 = ['a' => "1", 'b' => "2", 'c' => "3", 'z' => "4"];
$array2 = ['a' => "9", 'b' => "8", 'c' => "7", 'd' => "6", 'e' => "5"];
$result = [];
foreach ($array1 as $k => $v) {
$result[$k] = ['f1' => $v, 'f2' => "0"];
}
foreach ($array2 as $k => $v) {
$result[$k] = ['f1' => $result[$k]['f1'] ?? "0", 'f2' => $v];
}
var_export($result);
I need to convert string
"name1", "b", "2", "name2", "c", "3", "name3", "b", "2", ....
to an array like
$arr[0]['name'] = "name1";
$arr[0]['char'] = "b";
$arr[0]['qnt'] = "2";
$arr[1]['name'] = "name2";
$arr[1]['char'] = "c";
$arr[1]['qnt'] = "3";
$arr[2]['name'] = "name3";
$arr[2]['char'] = "b";
$arr[2]['qnt'] = "2";
I used explode to extract an string to array but it not work
Any idea?
$input = '"name1", "b", "2", "name2", "c", "3", "name3", "b", "2"';
$input = str_replace('"', '', $input);
$input = explode(', ', $input);
$output = array();
$i = 0;
while ($i < count($input)) {
$output[] = array(
'name' => $input[$i++],
'char' => $input[$i++],
'qnt' => $input[$i++]
);
}
print_r($output);
Output:
Array
(
[0] => Array
(
[name] => name1
[char] => b
[qnt] => 2
)
[1] => Array
(
[name] => name2
[char] => c
[qnt] => 3
)
[2] => Array
(
[name] => name3
[char] => b
[qnt] => 2
)
)
If you do not care about the array keys being numeric, you can do:
$string = 'name1, b, 2, name2, c, 3, name3, b, 2';
print_r( array_chunk( explode(',', $string), 3 ) );