i have array an with this result :
Array
(
[A] => Array
(
[0] => A
[1] => B
[2] => C
)
[B] => Array
(
[0] =>AA
[1] =>BB
[2] =>CC
)
[C] => Array
(
[0] =>AAA
[1] =>BBB
[2] =>CCC
)
)
i want to get like rows and print like with this result to each row:
A AA AAA
B BB BBB
C CC CCC
how to use foreach to print that result?
foreach ($result as $kk => $arr)
{
foreach($arr as $k=>$v)
{
if ( $k == 'A')
echo $arr[0];
if ( $k == 'B')
echo $arr[1];
if ( $k == 'B')
echo $arr[2]."<br />";
}
}
Create a new tmp variable for storing our new order.
$tmp = array();
How deep will the array go? In your example we go down 3 levels..
$depth = 3;
The array you want to sort
$result = array(
'a' => array( 'a', 'b', 'c' ),
'b' => array( 'aa', 'bb', 'cc' ),
'c' => array( 'aaa', 'bbb', 'ccc' ),
);
For each level in $result down to $depth.
for ($i=0; $i<$depth; $i++)
{
// Loop true our results and push them in to the right position in our $tmp array.
foreach ($result as $row)
{
$tmp[$i][] = $row[$i];
}
}
Output var_dump($tmp):
array(3) {
[0]=>
array(3) {
[0]=>
string(1) "a"
[1]=>
string(2) "aa"
[2]=>
string(3) "aaa"
}
[1]=>
array(3) {
[0]=>
string(1) "b"
[1]=>
string(2) "bb"
[2]=>
string(3) "bbb"
}
[2]=>
array(3) {
[0]=>
string(1) "c"
[1]=>
string(2) "cc"
[2]=>
string(3) "ccc"
}
}
And of course.. to print out your re-ordered array with foreach:
foreach($tmp as $row) {
echo "{$row[0]} {$row[1]} {$row[2]}";
}
will give you:
a aa aaa
b bb bbb
c cc ccc
If you denote your input as $hash, then $result will have the array in the form that you need:
$arr = array_values($hash);
$result = array();
$len = count($arr);
$lenNested = count($arr[0]);
for($i = 0; $i < $len; $i++){
for($j = 0; $j < $lenNested; $j++){
$result[$j][$i] = $arr[$i][$j];
}
}
This is just transposition of $hash. Now you can print out $result line by line.
Related
This question already has answers here:
Transpose 2d array, join second level with commas, and join first level with pipes
(5 answers)
Closed 7 months ago.
I have the following array.
$a = array("Algebra", "Arithmetic");
$b = array("08/01/2020", "08/02/2019");
$c = array("08/01/2020", "08/02/2019");
print_r($a);
print_r($b);
print_r($b);
and the output is
Array(
[0] => Algebra
[1] => Arithmetic
)
Array(
[0] => 08/01/2020
[1] => 08/01/2019
)
Array(
[0] => 08/02/2020
[1] => 08/02/2019
)
And I want Array in the following structure.
Array(
[0] => Algebra,08/01/2020,08/02/2020
[1] => Arithmetic,08/01/2019,08/02/2019
)
I have tried $results = array_merge_recursive($a, $b, $c); but its not giving desire output.
Thanks for help in advance.
A simple foreach loop will suffice
$a = array("Algebra", "Arithmetic");
$b = array("08/01/2020", "08/02/2019");
$c = array("08/01/2020", "08/02/2019");
foreach( $a as $i=>$v ) {
$new[] = sprintf( '%s,%s,%s', $v, $b[$i], $c[$i] );
}
Firstly, when you find yourself using sequentially-named variables it almost always means that they should actually be an array:
$a = array("Algebra", "Arithmetic");
$b = array("08/01/2020", "08/02/2019");
$c = array("08/01/2020", "08/02/2019");
$better_array = [$a, $b, $c];
var_dump($better_array);
Output:
array(3) {
[0]=>
array(2) {
[0]=>
string(7) "Algebra"
[1]=>
string(10) "Arithmetic"
}
[1]=>
array(2) {
[0]=>
string(10) "08/01/2020"
[1]=>
string(10) "08/02/2019"
}
[2]=>
array(2) {
[0]=>
string(10) "08/01/2020"
[1]=>
string(10) "08/02/2019"
}
}
Once they're in an proper array you can use array_column()
$out = [];
for($i=0, $c=count($better_array[0]); $i < $c; ++$i) {
$out[] = array_column($better_array, $i);
}
var_dump($out);
Output:
array(2) {
[0]=>
array(3) {
[0]=>
string(7) "Algebra"
[1]=>
string(10) "08/01/2020"
[2]=>
string(10) "08/01/2020"
}
[1]=>
array(3) {
[0]=>
string(10) "Arithmetic"
[1]=>
string(10) "08/02/2019"
[2]=>
string(10) "08/02/2019"
}
}
And if that comma-delimited string is what you actually want, then use implode():
$out = [];
for($i=0, $c=count($better_array[0]); $i < $c; ++$i) {
$out[] = implode(',', array_column($better_array, $i));
}
var_dump($out);
Output:
array(2) {
[0]=>
string(29) "Algebra,08/01/2020,08/01/2020"
[1]=>
string(32) "Arithmetic,08/02/2019,08/02/2019"
}
Lastly, you should avoid print_r() as it tends to produce misleading output. Eg: https://3v4l.org/ThSLb
You don't get anything built-in for this purpose. You need to build a custom function for this. You can try this-
<?php
$a = array("Algebra", "Arithmetic");
$b = array("08/01/2020", "08/01/2019");
$c = array("08/02/2020", "08/02/2019");
function mergeAssoc()
{
// You can get variable number of arguments|array by this.
$args = func_get_args();
$master = array();
foreach ($args as $arg)
{
foreach ($arg as $i => $v)
{
$master[$i][] = $v;
}
}
return $master;
}
$res = mergeAssoc($a, $b, $c);
print_r($res);
Note: It will return a multidimensional array. Not an array of comma-separated values.
Output:
Array
(
[0] => Array
(
[0] => Algebra
[1] => 08/01/2020
[2] => 08/02/2020
)
[1] => Array
(
[0] => Arithmetic
[1] => 08/01/2019
[2] => 08/02/2019
)
)
and if we use foreach then our desire output will be there with array separated by comma.
foreach ($res as $key => $value) {
$result[] = implode(',', $value);
}
and output of print_r($result); is
Array
(
[0] => Algebra,08/01/2020,08/02/2020
[1] => Arithmetic,08/01/2019,08/02/2019
)
I have this two arrays that are generated in two foreach loops and I want to set the first array as keys and the second one as values.
after I use this code
foreach ($difference AS $j) {
$fv = $cate->getFilterValueByFeatureID($j);
foreach ($fv AS $z) {
$array = array(
$j => $z
);
var_dump($array);
}
}
this is what I get
array(1) {
[6]=>
int(15)
}
array(1) {
[6]=>
int(20)
}
array(1) {
[8]=>
int(26)
}
array(1) {
[8]=>
int(27)
}
array(1) {
[8]=>
int(33)
}
and I want this result
array(1){
[6] => array(
[0] => 15
[1] => 20
)
array(1){
[8] => array(
[0] => 26
[1] => 27
[2] => 33
)
Like this (untested)
$result = [];
foreach ($difference AS $j) {
$fv = $cate->getFilterValueByFeatureID($j);
foreach ($fv AS $z) {
if(!isset($result[$j])) $result[$j] = [];
$result[$j][] = $z;
}
}
var_dump($result);
This question already has answers here:
PHP unique array by value?
(6 answers)
Closed 6 years ago.
I have a PHP array that looks like this,
[["a","b"],["e","j"],["a","s"]]
I need it to look like this,
[["a","b"],["e","j"]]
or this,
[["e","j"],["a","s"]]
I cannot have two inner arrays that contain the same "0" index. It does not matter which inner array is deleted as long as only one remains. How can I go through this array and remove inner arrays that contain the same "0" index?
Thanks!
You could simply loop through the array with two loops. Let's say this is your data:
$data = array(
array('a', 'b'),
array('e', 'j'),
array('a', 's'),
array('a', 't'),
array('c', 't'),
array('a', 'h'),
array('c', 'e'),
array('f', 'g')
);
Then you go ahead and loop through everything, and unset it if it's the same value.
$count = count($data);
foreach($data as $index => $array){
for($i=$index + 1; $i<$count; $i++)
if(isset($array[0]) && isset($data[$i][0]) && $array[0] == $data[$i][0])
unset($data[$i]);
}
The var_dump of $data after the loops would be:
array(4) {
[0]=>
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
}
[1]=>
array(2) {
[0]=>
string(1) "e"
[1]=>
string(1) "j"
}
[4]=>
array(2) {
[0]=>
string(1) "c"
[1]=>
string(1) "t"
}
[7]=>
array(2) {
[0]=>
string(1) "f"
[1]=>
string(1) "g"
}
}
<?php
$array = [["a","b"],["e","j"],["a","s"]];
$values = array();
foreach ($array as $key => $arrayChild) {
foreach ($arrayChild as $val) {
if (in_array($val, $values)) {
unset($array[$key]);
}
$values[] = $val;
}
}
print_r($array);
?>
Result:
Array (
[0] => Array ( [0] => a [1] => b )
[1] => Array ( [0] => e [1] => j )
)
I have a Relational Schema with attributes (A B C D).
I have a set of Functional Dependencies with me too.
Now I need to determine the closure for all the possible subsets of R's attributes. That's where I am stuck. I need to learn how to find subsets (non-repeating) in PHP.
My Array is stored like this.
$ATTRIBUTES = ('A', 'B', 'C', 'D').
so my subsets should be
$SUBSET = ('A', 'B', 'C', 'D', 'AB', 'AC', AD', 'BC', 'BD', 'CD', 'ABC', 'ABD', 'BCD', 'ABCD')
The code shouldn't be something big but for some reason I can't get my head around it.
Using php array_merge we can have a nice short powerSet function
function powerSet($array) {
// add the empty set
$results = [[]];
foreach ($array as $element) {
foreach ($results as $combination) {
$results[] = array_merge(array($element), $combination);
}
}
return $results;
}
You wish for the power set of $attributes? That is what your question implies.
An example can be found here (quoted for completeness)
<?php
/**
* Returns the power set of a one dimensional array, a 2-D array.
* [a,b,c] -> [ [a], [b], [c], [a, b], [a, c], [b, c], [a, b, c] ]
*/
function powerSet($in,$minLength = 1) {
$count = count($in);
$members = pow(2,$count);
$return = array();
for ($i = 0; $i < $members; $i++) {
$b = sprintf("%0".$count."b",$i);
$out = array();
for ($j = 0; $j < $count; $j++) {
if ($b{$j} == '1') $out[] = $in[$j];
}
if (count($out) >= $minLength) {
$return[] = $out;
}
}
return $return;
}
Here a backtracking solution.
given a function that returns all the L-lenght subsets of the input set, find all the L-lenght subsets from L = 2 to dataset input length
<?php
function subsets($S,$L) {
$a = $b = 0;
$subset = [];
$result = [];
while ($a < count($S)) {
$current = $S[$a++];
$subset[] = $current;
if (count($subset) == $L) {
$result[] = json_encode($subset);
array_pop($subset);
}
if ($a == count($S)) {
$a = ++$b;
$subset = [];
}
}
return $result;
}
$S = [ 'A', 'B', 'C', 'D'];
$L = 2;
// L = 1 -> no need to do anything
print_r($S);
for ($i = 2; $i <= count($S); $i++)
print_r(subsets($S,$i));
Based on #Yada's answer, this will generate the power set of an array, but preserve the original array's keys in each subset (the return value is still numerically & sequentially indexed). This very useful if you need subsets of an associative array.
The subsets also retain the element order of the original array. I added a stable sort to $results because I needed it, but you can omit it.
function power_set($array) {
$results = [[]];
foreach ($array as $key => $value) {
foreach ($results as $combination) {
$results[] = $combination + [$key => $value];
}
}
# array_shift($results); # uncomment if you don't want the empty set in your results
$order = array_map('count', $results);
uksort($results, function($key_a, $key_b) use ($order) {
$comp = $order[$key_a] - $order[$key_b]; # change only this to $order[$key_b] - $order[$key_a] for descending size
if ($comp == 0) {
$comp = $key_a - $key_b;
}
return $comp;
});
return array_values($results);
}
Given OP's input, var_dump(power_set(['A', 'B', 'C', 'D'])); provides:
array(16) {
[0] =>
array(0) {
}
[1] =>
array(1) {
[0] =>
string(1) "A"
}
[2] =>
array(1) {
[1] =>
string(1) "B"
}
[3] =>
array(1) {
[2] =>
string(1) "C"
}
[4] =>
array(1) {
[3] =>
string(1) "D"
}
[5] =>
array(2) {
[0] =>
string(1) "A"
[1] =>
string(1) "B"
}
[6] =>
array(2) {
[0] =>
string(1) "A"
[2] =>
string(1) "C"
}
[7] =>
array(2) {
[1] =>
string(1) "B"
[2] =>
string(1) "C"
}
[8] =>
array(2) {
[0] =>
string(1) "A"
[3] =>
string(1) "D"
}
[9] =>
array(2) {
[1] =>
string(1) "B"
[3] =>
string(1) "D"
}
[10] =>
array(2) {
[2] =>
string(1) "C"
[3] =>
string(1) "D"
}
[11] =>
array(3) {
[0] =>
string(1) "A"
[1] =>
string(1) "B"
[2] =>
string(1) "C"
}
[12] =>
array(3) {
[0] =>
string(1) "A"
[1] =>
string(1) "B"
[3] =>
string(1) "D"
}
[13] =>
array(3) {
[0] =>
string(1) "A"
[2] =>
string(1) "C"
[3] =>
string(1) "D"
}
[14] =>
array(3) {
[1] =>
string(1) "B"
[2] =>
string(1) "C"
[3] =>
string(1) "D"
}
[15] =>
array(4) {
[0] =>
string(1) "A"
[1] =>
string(1) "B"
[2] =>
string(1) "C"
[3] =>
string(1) "D"
}
}
Following #fbstj answer, I update the function:
Use bitwize operators instead of sprintf (#Titus comments)
Handle empty set (#James Stott & #fbstj comments)
Update syntax to PHP 7+
function powerSet(array $in, int $minLength = 0): array
{
$return = [];
if ($minLength === 0) {
$return[] = [];
}
for ($i = 1 << count($in); --$i;) {
$out = [];
foreach ($in as $j => $u) {
if ($i >> $j & 1) {
$out[] = $u;
}
}
if (count($out) >= $minLength) {
$return[] = $out;
}
}
return $return;
}
Since power set functions can increase by a lot the memory load (2count($in) iterations), consider using Generator:
function powerSet(array $in, int $minLength = 0): \Generator
{
if ($minLength === 0) {
yield [];
}
for ($i = 1 << count($in); --$i;) {
$out = [];
foreach ($in as $j => $u) {
if ($i >> $j & 1) {
$out[] = $u;
}
}
if (count($out) >= $minLength) {
yield $out;
}
}
}
Usage:
foreach (powerSet(range(1, 10)) as $value) {
echo implode(', ', $value) . "\n";
}
I have pairs of items in an PHP array. Example:
<?php
$elements = array(
'tiger'=>'lion',
'car'=>'bike',
'lion'=>'zoo',
'truck'=>'plane'
);
?>
Now I want to combine these items so that all items which are connected in any way go to one group. Continuation of the example above:
<?php
$groups = array(
0=>array('tiger', 'lion', 'zoo'),
1=>array('car', 'bike'),
2=>array('truck', 'plane'
);
?>
Is this understandable? How could I achieve this?
I'm looking for a function which does this.
<?php
$elements = array(
'tiger' => 'lion',
'car' => 'bike',
'lion' => 'zoo',
'truck' => 'plane'
);
$groups = array();
foreach ($elements as $key => $val) {
$appended = false;
foreach ($groups as &$group) {
if ($group[0] == $key) {
array_unshift($group, $val);
$appended = true;
break;
}
}
if (!$appended) {
$groups[] = array($val, $key);
}
}
var_dump($groups);
Gives:
array(3) {
[0]=>
array(3) {
[0]=>
string(3) "zoo"
[1]=>
string(4) "lion"
[2]=>
string(5) "tiger"
}
[1]=>
&array(2) {
[0]=>
string(4) "bike"
[1]=>
string(3) "car"
}
[2]=>
array(2) {
[0]=>
string(5) "plane"
[1]=>
string(5) "truck"
}
}
Here's an O(n) solution:
$elements = array(
'tiger' => 'lion',
'car' => 'bike',
'lion' => 'zoo',
'truck' => 'plane'
);
$groups = array();
$sub = array();
$ignore = array();
foreach ( $elements as $key=>$value ) {
if ( isset($ignore[$key]) ) {
continue;
}
$sub = array($key, $value);
if ( isset($elements[$value]) ) {
$ignore[$value] = 1;
$sub[] = $elements[$value];
}
$groups[] = $sub;
}
print_r($groups);
Result:
Array
(
[0] => Array
(
[0] => tiger
[1] => lion
[2] => zoo
)
[1] => Array
(
[0] => car
[1] => bike
)
[2] => Array
(
[0] => truck
[1] => plane
)
)
The idea is simple:
Create a new array to hold your groups
Loop over the item array
Check if the group for the item exists in the group array - if it does not, create it
Put item in group