I have an array on input with ids of graphic elements and I need to find groups of them. I was trying to use array_search and array_marge but without success.
I have array of siblings:
'siblings' =>
array (size=6)
0 =>
array (size=2)
0 => int 0
1 => int 1
1 =>
array (size=2)
0 => int 2
1 => int 3
2 =>
array (size=2)
0 => int 3
1 => int 5
3 =>
array (size=2)
0 => int 4
1 => int 6
4 =>
array (size=2)
0 => int 4
1 => int 7
5 =>
array (size=2)
0 => int 6
1 => int 7
I need output like following:
'groups' =>
array (size=6)
0 =>
array (size=2)
0 => int 0
1 => int 1
1 =>
array (size=2)
0 => int 2
1 => int 3
2 => int 5
2 =>
array (size=2)
0 => int 4
1 => int 6
2 => int 7
I can output this by following:
$groups[] = array_unique(array_merge($siblings[0]));
$groups[] = array_unique(array_merge($siblings[1],$siblings[2]));
$groups[] = array_unique(array_merge($siblings[3],$siblings[4],$siblings[5]));
var_dump($groups); // will output the previous output of groups
But I need function that will work on large scale.
It may not be so efficient but it works. The normal idea is loop through the array, check the intersection of the current with the remaining inner arrays. If there is some intersection, just merge them into the current, otherwise prepare the next arrays set (to loop and extract the next group):
$a = array('siblings' => array(array(0,1),array(2,3),array(3,5),
array(4,6),array(4,7),array(6,7)));
$g[] = $a["siblings"][0];
$round = array_slice($a["siblings"],1);
$temp = array();
$i = 0;
while(count($round) > 0){
$v = array_shift($round);
if(count(array_intersect($g[$i],$v)) > 0)
$g[$i] = array_unique(array_merge($g[$i],$v));
else $temp[] = $v;
if(count($round) == 0 && count($temp) > 0) {
$g[] = $temp[0];
$i++;
$round = array_slice($temp,1);
$temp = array();
}
}
$groups["groups"] = $g;
var_dump($groups);
Result:
array(1) {
["groups"]=> array(3) {
[0]=> array(2) {
[0]=> int(0)
[1]=> int(1) }
[1]=> array(3) {
[0]=> int(2)
[1]=> int(3)
[3]=> int(5) }
[2]=> array(3) {
[0]=> int(4)
[1]=> int(6)
[2]=> int(7) } } }
Perhaps something like this would work. It doesn't compare siblings against each other. Instead it flattens the array, removes duplicates and then breaks it into groups of 3.
<?php
$siblings = array(
array(0, 1),
array(2, 3),
array(3, 5),
array(4, 6),
array(4, 7),
array(6, 7),
);
$merged = array();
$grouped = array();
for ($i = 0; $i < count($siblings); $i++) {
array_push($merged, $siblings[$i][0]);
array_push($merged, $siblings[$i][1]);
}
$merged = array_unique($merged);
$merged = array_chunk($merged, 3);
print_r($merged);
?>
Gives the following output:
Array
(
[0] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[1] => Array
(
[0] => 3
[1] => 5
[2] => 4
)
[2] => Array
(
[0] => 6
[1] => 7
)
)
Related
I have a question for you.
My PHP code is composed by these below arrays and my intention is to merge them into one, as you can see at the bottom of the topic.
These arrays are divided into 2 different variables: $array1 and $array2.
Array ($array1)
(
[0] => 2016-11-11
[1] => 2016-11-10
[2] => 2016-11-09
[3] => 2016-11-08
[4] => 2016-11-07
[5] => 2016-11-06
[6] => 2016-11-05
)
1
Array ($array2)
(
[2016-11-11] => 0
[2016-11-10] => 0
[2016-11-08] => 0
[2016-11-07] => 0
[2016-11-06] => 0
)
1
And this is what I expect this program will do:
Array
(
[2016-11-11] => 0,
[2016-11-10] => 0,
[2016-11-09] => NULL,
[2016-11-08] => 0,
[2016-11-07] => 0,
[2016-11-06] => 0,
[2016-11-05] => NULL
)
1
How can I set my code so that it returns me the previous array? How can I solve this problem? Can anyone help me?
I tried:
$array1 = array(
"2016-11-11",
"2016-11-10",
"2016-11-09",
"2016-11-08",
"2016-11-07",
"2016-11-06",
"2016-11-05"
);
$array2 = array();
while($row1 = $result1->fetch_assoc())
{
$array2[$row1["datesend"]] = $row1["error"];
}
This code will work for you:
$array1 = array('2016-11-11','2016-11-10','2016-11-09','2016-11-08','2016-11-07','2016-11-06','2016-11-05');
$array2 = array('2016-11-11' => 0,'2016-11-10' => 0,'2016-11-08' => 0,'2016-11-07' => 0,'2016-11-06' => 0);
$result = array();
foreach($array1 as $a){
if(isset($array2[$a]))
$result[$a] = $array2[$a];
else
$result[$a] = NULL;
}
echo '<pre>';
var_dump($result);
echo '</pre>'
Outpur is:
array(7) {
["2016-11-11"]=>
int(0)
["2016-11-10"]=>
int(0)
["2016-11-09"]=>
NULL
["2016-11-08"]=>
int(0)
["2016-11-07"]=>
int(0)
["2016-11-06"]=>
int(0)
["2016-11-05"]=>
NULL
}
I hope it helps
I have this code
$a1 = array(
'success' => TRUE,
'data' => array(
'foo' =>
array(
21 =>
array(
1 =>
array(1, 2, 3, 4, 5)
)
)
)
);
$a2 = array(
'success' => TRUE,
'data' => array(
'foo' =>
array(
21 =>
array(
7 =>
array(6, 7, 8, 9, 10)
)
)
)
);
$results = array();
$results = array_merge_recursive($results, $a1['data']);
$results = array_merge_recursive($results, $a2['data']);
var_dump($results);
From what I understood of array_merge_recursive(), I am expecting the results would be
array
'foo' =>
array
21 =>
array
1 =>
array
0 => int 1
1 => int 2
2 => int 3
3 => int 4
4 => int 5
7 =>
0 => int 6
1 => int 7
2 => int 8
3 => int 9
4 => int 10
Instead I get this
array
'foo' =>
array
21 =>
array
1 =>
array
0 => int 1
1 => int 2
2 => int 3
3 => int 4
4 => int 5
22 =>
array
7 =>
array
0 => int 6
1 => int 7
2 => int 8
3 => int 9
4 => int 10
Where did the 22 index come from? Why is it outputting differently? Did I use the function wrong?
array_merge_recursive merges elements/arrays from the same depth as the first array, but if both arrays the key is a numerical index and they are the same it then appends to it. This is what is happening in your situation. since then your array is appended at 2nd level where index 21 is found by creating index 22. To receive the desired output you have change your index 21 to a string key like "x21"
Notes from php manual
If the input arrays have the same string keys, then the values for
these keys are merged together into an array, and this is done
recursively, so that if one of the values is an array itself, the
function will merge it with a corresponding entry in another array
too. If, however, the arrays have the same numeric key, the later
value will not overwrite the original value, but will be appended.
I just came across the same issue, I wanted to merge the arrays but surprisingly found the keys were changed automatically in the result. The reason was because my "keys" are string of decimal numbers, without any alphabetic characters.
But luckily I noticed that if the keys have alphabetic characters, they could be reserved. So just came up with the following idea, which would append a letter 'S' to each key recursively before the merge, and later remove it in the final result.
Please refer to the enhanced_array_merge_recursive function for details:
<?php
$aa = [
'10' => 'book',
'14' => ['cat'],
];
$ab = [
'12' => 'cd',
'18' => 'cup',
'14' => ['dog'],
];
var_dump(enhanced_array_merge_recursive($aa, $ab));
function revise_keys($source)
{
if (!is_array($source)) {
return $source;
}
$target = [];
foreach ($source as $key => $value) {
$target['S' . $key] = revise_keys($value);
}
return $target;
}
function revert_keys($source)
{
if (!is_array($source)) {
return $source;
}
$target = [];
foreach ($source as $key => $value) {
$target[substr($key, 1 - strlen($key))] = revert_keys($value);
}
return $target;
}
function enhanced_array_merge_recursive(...$candidates)
{
$merged = [];
foreach ($candidates as $candidate) {
if (!is_array($candidate)) {
continue;
}
$merged = array_merge_recursive($merged, revise_keys($candidate));
}
return revert_keys($merged);
}
Output looks like following:
array(4) {
[10] =>
string(4) "book"
[14] =>
array(1) {
[0] =>
array(2) {
[0] =>
string(3) "cat"
[1] =>
string(3) "dog"
}
}
[12] =>
string(2) "cd"
[18] =>
string(3) "cup"
}
CODE 1: Reading data from Excel sheet. Containing 12 Different values.
The values are : 48,600,5.3,5,1500,6000,85,30,70,30,70,14 .
$BATTCONFIG=$objPHPExcel->getActiveSheet()->rangetoArray('C9:C20',null,true,true,true);
CODE 2: Trying to convert all VALUES in the array $BATTCONFIG to INTEGER using FOR loop.
$y1 = (array_values($BATTCONFIG));
var_dump(y1);
for( $i=0 ; $i<=11 ; $i++ )
{
settype($y1[$i], "integer");
}
var_dump($y1);
But I am not getting the desiered output , I am getting all the values as 1 .
MY OUTPUT:
Before SETTYPE():
array (size=12)
0 =>
array (size=1)
'C' => float 48
1 =>
array (size=1)
'C' => int 600
2 =>
array (size=1)
'C' => float 0.3
3 =>
array (size=1)
'C' => int 5
4 =>
array (size=1)
'C' => float 1500
5 =>
array (size=1)
'C' => int 6000
6 =>
array (size=1)
'C' => int 85
7 =>
array (size=1)
'C' => int 30
8 =>
array (size=1)
'C' => int 70
9 =>
array (size=1)
'C' => int 30
10 =>
array (size=1)
'C' => int 70
11 =>
array (size=1)
'C' => float 14
AFTER SETTYPE():
array (size=12)
0 => int 1
1 => int 1
2 => int 1
3 => int 1
4 => int 1
5 => int 1
6 => int 1
7 => int 1
8 => int 1
9 => int 1
10 => int 1
11 => int 1
Please help me out . I need these Integer values as output to plot my Graph.
Thank you in advance.
There must be another error when populating $y1 with its values. Imagine this simplified example which works as expected:
$arr = array('1','2','3','4','5');
for ($i = 0; $i < 5; $i++) {
settype($arr[$i], "integer");
}
var_dump($arr);
What gives you :
array(5) {
[0] =>
int(1)
[1] =>
int(2)
[2] =>
int(3)
[3] =>
int(4)
[4] =>
int(5)
}
After edit of the question (now having $y1 before conversion) it points out, that you aren't aware of that $y1 is multidimensional array. You'll have to change to code to something like this:
$ints = array();
foreach($y1 as $index => $cell) {
$values = array_values($cell);
$ints []= intval(round($values[0]));
}
var_dump($ints);
Also note, that you are trying to convert floats to int using the settype() function. I would use round() for that
I have an array:
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[5] => 5
[6] => 6
[7] => 7
[8] => 8
[9] => 9
)
I want to split the array into alternating chunks. (size 2 then 3 then 2 then 3 etc)
Array
(
[0] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[1] => Array
(
[0] => 3
[1] => 4
)
[2] => Array
(
[0] => 5
[1] => 6
[2] => 7
)
[3] => Array
(
[0] => 8
[1] => 9
)
)
That should work:
$a = array(0 => 0,1 => 1,2 => 2,3 => 3,4 => 4, 5 => 5, 6 => 6,7 => 7,8 => 8,9 => 9);
$chunks = array();
$i=1;
while(count($a)){
$chunks[] = array_splice($a, 0,(2+($i%2)),array());
$i++;
}
echo "<pre>";
var_dump($chunks);
You can use array_splice for splitting the array, but you need to set conditions right? On what basis do you wanna split them?
And you can use array_merge to bring them back into an array of arrays.
In case of your current code, the code will be:
PHP Code
<?php
$array = array(0,1,2,3,4,5,6,7,8,9);
$final = array(
array_splice($array, 0, 3),
array_splice($array, 1, 2),
array_splice($array, 1, 2),
array_splice($array, 1, 2),
);
print_r($final);
?>
Output
Array
(
[0] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[1] => Array
(
[0] => 4
[1] => 5
)
[2] => Array
(
[0] => 6
[1] => 7
)
[3] => Array
(
[0] => 8
[1] => 9
)
)
Fiddle here: http://codepad.org/JzxcZ2Q1
Iterated calls of array_splice() seems like a great way to go. Here is a cleaner version of István Őri's answer. Subtracting from 5 removes the need to use the modulus operator.
Code: (Demo)
$array = range(1, 10);
$chunks = [];
$chunkSize = 3;
while ($array) {
$chunkSize = 5 - $chunkSize;
$chunks[] = array_splice($array, 0, $chunkSize);
}
var_export($chunks);
This snippet modifies $array as it iterates. array_splice() keeps removing elements from the front of the array. Eventually the array will become empty and the while() condition will fail -- breaking the loop.
You could use this, it isn't the most elegant, but it will just do the trick for you - and you can modify it nicely and adapt it to suit your purposes further:
<?php
$originalArray = array(0,1,2,3,4,5,6,7,8,9);
$counter=count($originalArray);
$isTwo=true;
$newArray=array();
$arrElement=0;
$i=0;
while($i<$counter)
{
if($isTwo)
{
$newArray[$arrElement]= array();
for($j=0; $j<2; $j++)
{
$newArray[$arrElement][$j]=$originalArray[$i+$j];
}
$i+=2;
$isTwo=false;
$arrElement++;
}
else
{
$newArray[$arrElement]= array();
for($j=0; $j<3; $j++)
{
$newArray[$arrElement][$j]=$originalArray[$i+$j];
}
$i+=3;
$isTwo=true;
$arrElement++;
}
}
var_dump($newArray);
?>
Output:
array(4) {
[0]=>
array(2) {
[0]=>
int(0)
[1]=>
int(1)
}
[1]=>
array(3) {
[0]=>
int(2)
[1]=>
int(3)
[2]=>
int(4)
}
[2]=>
array(2) {
[0]=>
int(5)
[1]=>
int(6)
}
[3]=>
array(3) {
[0]=>
int(7)
[1]=>
int(8)
[2]=>
int(9)
}
}
$tobechunked_arr = array(0,1,2,3,4,5,6,7,8,9);
$chunk_size_arr = array(3,2,3,2);
$j = 0;
foreach($chunk_size_arr as $key => $val)
{
for($i = 0; $i < $val; $i++)
{
$result_arr[$key][] = $tobechunked_arr[$j];
$j++;
}
}
echo "<pre>";
print_r($result_arr);
try this
<?php
$input_array = array('a', 'b', 'c', 'd', 'e');
print_r(array_chunk($input_array, 2));
print_r(array_chunk($input_array, 2, true));
?>
Update
<?php
$myArray = array("abc","def","ghi","jkl","mno","pqr","stu","vwx","yz");
$newArray = array_chunk($myArray, 2, false);
// Now process the multidimensional array made from array_chunk()
$i = 0;
foreach ($newArray as $inner_array) {
$i++;
echo "<h2>Chunk $i</h2>";
while (list($key, $value) = each($inner_array)) {
echo "$key: $value <br />";
}
}
?>
Output
Chunk 1
0: abc
1: def
Chunk 2
0: ghi
1: jkl
Chunk 3
0: mno
1: pqr
Chunk 4
0: stu
1: vwx
Chunk 5
0: yz
Arrays have been comprehensively covered but am still stumped about how to go around this. I have two arrays which i want to merge without overwriting duplicate keys i.e.
Array1
(
[0] => 0
[1] => 1
[2] => 1
[3] => 1
[4] => 1
[5] => 0
[6] => 0
)
+
Array2
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 1
)
my ideal result is
Array1 + Array2
(
[0] => 0
[1] => 1
[2] => 1
[3] => 1
[4] => 1
[5] => 0
[6] => 1
)
How would i do this? I've tried using + but it gives the first array as the result
What you want to do is to map both arrays into single array, containing max value from two respective values, like that:
$array1 = array(0, 1, 1, 1, 1, 0, 0);
$array2 = array(0, 0, 0, 0, 0, 0, 1);
$result = array_map('max', $array1, $array2);
See the result here: http://ideone.com/clone/MN568
It looks like that:
array(7) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(1)
[3]=>
int(1)
[4]=>
int(1)
[5]=>
int(0)
[6]=>
int(1)
}
array_merge() does not overwrite duplicate elements that have numeric keys.
Given the arrays are of the same length:
function bitwise_or_arrays($arr1, $arr2) {
$result = array();
for ($i = 0; $i < count($arr1); $i++) {
$result[$i] = $arr1 | $arr2;
}
return $result;
}
If you are looking for the greater (nonzero) of the two arrays, you can iterate like so:
$array1 = array(1,0,0,1,1,1);
$array2 = array(0,0,1,0,0,1);
$newarr = array();
foreach ($array1 as $k => $v) {
$newarr[$k] = max($array1[$k], $array2[$k]);
}
print_r($newarr);
Array
(
[0] => 1
[1] => 0
[2] => 1
[3] => 1
[4] => 1
[5] => 1
)
If what you need is to add the values, use:
$newarr = array();
foreach ($array1 as $k => $v) {
$newarr[$k] = $array1[$k] + $array2[$k];
}
Just for fun (although in your case with 0 and 1 values it works :)
$array1 = array(0, 1, 1, 1, 1, 0, 0);
$array2 = array(0, 0, 0, 0, 0, 0, 1);
$str1 = implode('', $array1);
$str2 = implode('', $array2);
$result = str_split($str1 | $str2);
Sorry for this variant, I know it's crazy, but just couldn't not to post it. Arrays look like bit masks 0111100 and 0000001. So just using bitwise | operator.
So result:
Array
(
[0] => 0
[1] => 1
[2] => 1
[3] => 1
[4] => 1
[5] => 0
[6] => 1
)
If what your looking is to combine them use array_combine().
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);
print_r($c);
//*output:
array(
[green] => avocado
[red] => apple
[yellow] => banana
)
here's how to merge array:
$beginning = 'foo';
$end = array(1 => 'bar');
$result = array_merge((array)$beginning, (array)$end);
print_r($result);
//output:
Array(
[0] => foo
[1] => bar
)
heres how to add values
$a = array(0=>1, 1=>2, 2=>3, 3=>4);
$b = array(0=>5, 1=>6, 2=>7, 3=>8);
$c = $a[0] += $b[0];
print_r($c);//output: 6
im not a guru on php but i hope this helps you even just abit.
Just for the fun of it:
$array1 = array(0,1,1,1,1,0,0);
$array2 = array(0,0,0,0,0,0,1);
$array3 = str_split(decbin(bindec(implode('',$array1)) | bindec(implode('',$array2))));
var_dump($array3);
Unfortunately it trims leading zeroes
Using
$array3 = str_split(str_pad(decbin(bindec(implode('',$array1)) | bindec(implode('',$array2))),count($array1),'0',STR_PAD_LEFT));
will restore leading zeroes, but doesn't feel as clean