I have this array where I need to remove any item where inTOC is 0 (ie. false) while keeping the index to be able to loop using for.
This is the array:
Array
(
[0] => Array
(
[name] => JAL
[id] => 798162f0-d779-46b6-96cb-ede246bf4f3f
[inTOC] => 1
[children] => Array
(
[0] => Array
(
[name] => BRU
[id] => 5600b395-4a28-4956-ccbf-9b238c4fa432
[inTOC] => 0
)
[1] => Array
(
[name] => TEW
[id] => 9e2ebbf6-1c81-4ff7-feb5-c5bede2ccd6c
[inTOC] => 1
)
)
)
[1] => Array
(
[name] => ABC
[id] => 761e1909-34b3-4733-aab6-ebef26d3fcb9
[inTOC] => 1
)
)
This is the function I have so far where I tried unset which doesn't rebase and array_splice which only removes a child node when the goal is to remove the array:
public function tocFilterNonTOC($tree){
$size = count($tree);
for ($i = 0; $i < $size; $i++) {
if ($tree[$i]['inTOC']) {
$this->tocFilterNonTOC($tree[$i]['children']);
} else {
array_splice($tree[$i], $i, 1); // removes the 'name' node (BRU) only
}
}
}
In the end, I went back to using unset but added array_values to the recursive function like so:
public function tocFilterNonTOC($tree){
$size = count($tree);
for ($i = 0; $i < $size; $i++) {
if ($tree[$i]['inTOC']) {
$this->tocFilterNonTOC($tree[$i]['children']);
} else {
unset($tree[$i]);
}
}
if ($tree!=null && is_array($tree)) $tree = array_values($tree)
}
Related
This question already has answers here:
How to Flatten a Multidimensional Array?
(31 answers)
Closed 4 years ago.
I have some problems with parent array that contains multiple children array. It will be necessary that the array children, does not contain themselves other children array, but if it is the case, then to raise these array grandchildren at the level of children.
[0] => Array (
[0] => Array (
[name] => ...
[count] => ...
[url] => ...
[html] => ...
)
[1] => Array (
[name] => ...
[count] => ...
[url] => ...
)
[2] => Array (
[1] => Array (
[name] => ...
[count] => ...
[url] => ...
[html] => ...
)
[2] => Array (
[name] => ...
[count] => ...
[url] => ...
)
)
[3] => Array (
[name] => ...
[count] => ...
[url] => ...
)
[4] => Array (
[name] => ...
[count] => ...
[url] => ...
)
);
In the example array["2"] contain 2 array, I want that the 2 array go up one level and so become brothers and not children.
Can you help me please with the right function ?
function transformMultipleArraysTo1(array $multipleArrays = null)
{
$newArray = array();
if (!isArrayEmpty($multipleArrays)) {
foreach ($multipleArrays as $array) {
if (is_array($array)) {
foreach ($array as $singleArray) {
if (is_array($singleArray)) {
$newArray[] = $singleArray;
} else {
continue 2;
}
}
$newArray[] = $array;
}
}
}
return $newArray;
}
Many thanks
I came up with this solution, not the prettiest, but it works.
function RemoveThoseNastyGrandchildren(array $array = NULL){
foreach ($array as $ckey => $child) {
foreach($child as $gckey => $grandchild){
if(is_array($grandchild)){
$array[] = $grandchild;
array_splice($array[$ckey],$gckey);
}
}
}
$length = count($array);
for($i = 0; $i < $length ; $i++){
if(!empty($array[$i][0]) && is_array($array[$i][0])){
array_splice($array,$i,1);
$i = -1;
$length = count($array);
}
}
//print("<pre>".print_r($array,true)."</pre>"); <---- To print it pretty uncomment
return $array;
}
The First Loop:
will iterate through all relatives, looking for the potential grandchildren. If it finds one of these nasty grandchildren it'll append it to their parents, becoming a grandchildren again.
After that we just have to disensamble the former grandchildrens bodies, and that's what ...
The Second Loop does:
It's iterating through the changed array, looking for empty bodies.
Then return the freshly shaped array familytree and whooosh, you got rid of those GCs.
I have a multidimensional array. I want to get array element which value is greater than 2 and less than 17. My Array is given below:
Array
(
[4] => Array
(
[0] => 17
[1] => 15
[2] => 12
)
[5] => Array
(
[0] => 16
)
[2] => Array
(
[0] => 3
[1] => 1
)
[1] => Array
(
[0] => 2
)
)
I want output like below:
Array
(
[4] => Array
(
[0] => 17
[1] => 15
[2] => 12
)
[5] => Array
(
[0] => 16
)
[2] => Array
(
[0] => 3
[1] => 1
)
)
Please help me how can I do it easy & fast method.
You can use a nested array filter.
$result = array_filter($outer_array, function($inner_array) {
return array_filter($inner_array, function($number) {
return $number > 2 && $number < 17;
});
});
Then inner array filter will result in an empty array being passed to the outer array filter if no values are found in the specified range. The empty array will evaluate to false in the outer filter callback, eliminating that array from the result.
Demo at 3v4l.org.
Generally, we want you to show what you have tried before we'll write code for you, but this one's on the house. For future reference, include some code snippets along with your question to avoid getting downvoted.
$output = array();
for($i = 0; $i < count($arr); $i++)
{
$use = false;
for($j = 0; $j < count($arr[$i]); $j++)
{
if($arr[$i][$j] > 2 and $arr[$i][$j] < 17)
{
$use = true;
break;
}
}
if($use)
$output[] = $arr[$i];
}
return $output;
This question already has answers here:
Php recursive array counting
(7 answers)
Closed 4 months ago.
I try to make recursive function to count elements on array "levels". But can't do that for two hours already. Check example array:
Array (
[0] => Array (
[0] => Array (
[0] => Array ( )
[1] => Array ( )
)
[1] => Array ( )
)
[1] => Array (
[0] => Array (
[0] => Array (
[0] => Array ( )
[1] => Array ( )
)
)
)
)
The resulting array that count elements on different levels will be:
Array ([0] => 2, [1] => 3, [2] => 3, [3] => 2)
I made function for count total array elements, but no idea how to count each "level"
function countTotalArr($arr, $lvl) {
if ($lvl != 0) $cnt = 1;
else $cnt = 0; // don't count zero level
for ($i = 0; $i < count($arr); $i++)
$cnt += countArr($arr[$i], $lvl + 1);
return $cnt;
}
$total = countTotalArr($referralsCount, 0);
Another solution using while:
// $array is your array at the beginning of iteration
$depthMap = [];
$currentDepth = 0;
while(true) {
$depthMap[$currentDepth] = count($array);
$carry = [];
foreach($array as $item) {
if(is_array($item)) {
$carry = array_merge($carry, $item);
}
}
if(count($carry) < 1) {
break;
}
$array = $carry;
$currentDepth++;
}
Try this code:
<?php
$array = Array (
0 => Array (
0 => Array (
0 => Array ( ) ,
1 => Array ( ) ,
) ,
1 => Array ( ) ,
) ,
1 => Array (
0 => Array (
0 => Array (
0 => Array ( ),
1 => Array ( ),
),
),
) ,
);
function countTotalArr($arr, $lvl)
{
$result = array();
$countOnLevel = count($arr);
$result[$lvl] = $countOnLevel;
$tempArray = array();
foreach($arr as $index => $singleArray)
{
foreach($singleArray as $singleSubArray)
if(is_array($singleSubArray))
$tempArray[] = $singleSubArray;
}
if(!empty($tempArray))
{
$levelTemp = $lvl + 1;
$result = array_merge($result, countTotalArr($tempArray, $levelTemp));
}
return $result;
}
$total = countTotalArr($array, 0);
echo '<pre>';
print_r($total);
Result of print_r($total) is:
Array
(
[0] => 2
[1] => 3
[2] => 3
[3] => 2
)
Having some difficulty trying to do this. I'm fetching an array of all submissions, and they are being returned in an array like this:
Array
(
[0] => Array
(
[Submission] => Array
(
[user_id] => 2
[title] => This is a test, only a test
[source] => http://www.testing.com
[slug] => this-is-a-test-only-a-test
[category] => misc
[created] => 2012-10-05 03:43:11
[id] => 110
)
[SubmissionsVote] => Array
(
[0] => Array
(
[id] => 336
[user_id] => 2
[submission_id] => 110
[vote_type] => up
)
)
(
[1] => Array
(
[id] => 337
[user_id] => 4
[submission_id] => 110
[vote_type] => down
)
)
)
)
My intent is to loop through that returned array, and grab all the SubmissionsVote by vote_type == up and vote_type == down.
I then want to calculate a score (this example would return a score of 0 which is just: up - down. With that, I want to put that score into an array and append it to the end of the original one so it'd look like:
Array
(
[0] => Array
(
[Submission] => Array
(
[user_id] => 2
[title] => This is a test, only a test
[source] => http://www.testing.com
[slug] => this-is-a-test-only-a-test
[category] => misc
[created] => 2012-10-05 03:43:11
[id] => 110
)
[SubmissionsVote] => Array
(
[0] => Array
(
[id] => 336
[user_id] => 2
[submission_id] => 110
[vote_type] => up
)
)
(
[1] => Array
(
[id] => 337
[user_id] => 4
[submission_id] => 110
[vote_type] => down
)
)
[SubmissionScore] => Array
(
[0] => 0
)
)
)
Here is what I am doing unsuccessfully:
$votes = array();
$totalScore = array();
foreach ($submissions as $submission) {
$vote = $submission['SubmissionsVote'];
array_push($votes, $vote);
}
for ($i = 0; $i < count($votes); $i++) {
$downVotes = 0;
$upVotes = 0;
if ($votes[$i]['vote_type'] == 'down') {
$downVotes += 1;
} else if ($votes[$i]['vote_type'] == 'up') {
$upVotes += 1;
}
$score = $upVotes - $downVotes;
$totalScore = array_push($totalScore, $score);
}
Would love to get a little push in the right direction here.
Try this one:
$newSubmissions = array();
foreach ($submissions as $submission) {
$SubmissionsVote = $submission['SubmissionsVote'];
foreach($SubmissionsVote as $votes) {
$score = 0;
if ($votes['vote_type'] == 'down') {
$score -= 1;
} else if ($votes['vote_type'] == 'up') {
$score += 1;
}
$submission['SubmissionScore'] = array($score);
}
$newSubmissions[] = $submission;
}
$submissions = $newSubmissions;
I see at least two errors in your code :
You never set SubmissionScore in your array to $totalScore value.
Even if you add a $votes[$i]['SubmissionScore'] = $totalScore, that will not work, in PHP only object are passed by reference so $votes will only contain copy.
There are multiple possibility to resolve the problem but a reference in the foreach is a good choice :
foreach ($submissions as &$submission) {
$totalScore = 0;
foreach ($submission['SubmissionsVote'] as $vote) {
if ($vote['vote_type'] == 'down') {
$totalScore--;
} else if ($vote['vote_type'] == 'up') {
$totalScore++;
}
}
$submission['SubmissionScore'] = $totalScore;
}
Each submission will now have a SubmissionScore based on up/down vote.
You are initializing $downVotes and $upVotes inside a loop, that means you override values each time you iterate through the array.
Anyway, you could simplify this.
foreach ($submissions as $index => $submission) {
$up = 0;
$down = 0;
foreach ($submission['SubmissionsVote'] as $vote) {
if ($vote['vote_type'] == 'up') {
$up++;
} else {
$down++;
}
}
$submissions[$index]['SubmissionScore'] = $up - $down;
}
I'm trying to process an uploaded CSV file into an array in PHP. I have that working fine, but some files from users end up have a bunch of blank rows with delimiters. This usually happens when they use Excel on an existing file. Highlighting the old cells and just clearing them.
Sample CSV File
lineNo,date,vendor,amount
1,5/2/2012,V000236,3727.21
2,5/2/2012,V003432,4826.19
,,,
,,,
Becomes the following array
Array
(
[0] => Array
(
[0] => lineNo
[1] => date
[2] => vendor
[3] => amount
)
[1] => Array
(
[0] => 1
[1] => 5/2/2012
[2] => V000236
[3] => 3727.21
)
[2] => Array
(
[0] => 2
[1] => 5/2/2012
[2] => V003432
[3] => 4826.19
)
[3] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
)
[4] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
)
)
I don't want to just remove any blank rows, I want to stop after array index 2. Go easy on my function I'm new :P
function csvToArray($csvFile, $specialChars = FALSE) {
$arrayCSV = array();
if (($csvHandle = fopen($csvFile, "r")) !== FALSE) { // Open the CSV
$csvKey = 0; // Set the parent array key to 0
while (($csvData = fgetcsv($csvHandle)) !== FALSE) {
$c = count($csvData); // Count the total keys in each row
//need something to stop on blank delimiter rows ,,,
for ($x = 0; $x < $c; $x++) { //Populate the array
if ($specialChars === TRUE) {
$arrayCSV[$csvKey][$x] = htmlspecialchars($csvData[$x]);
} else {
$arrayCSV[$csvKey][$x] = $csvData[$x];
}
}
$csvKey++;
}
fclose($csvHandle);
}
return $arrayCSV;
}
Ultimately, I'd like this returned
Array
(
[0] => Array
(
[0] => lineNo
[1] => date
[2] => vendor
[3] => amount
)
[1] => Array
(
[0] => 1
[1] => 5/2/2012
[2] => V000236
[3] => 3727.21
)
[2] => Array
(
[0] => 2
[1] => 5/2/2012
[2] => V003432
[3] => 4826.19
)
)
Can't you break; your while loop as soon as you find an empty value?
if (($csvHandle = fopen($csvFile, "r")) !== FALSE) { // Open the CSV
$csvKey = 0; // Set the parent array key to 0
while (($csvData = fgetcsv($csvHandle)) !== FALSE) {
$c = count($csvData); // Count the total keys in each row
// ## Flag variable ##########
$empty = true;
for ($x = 0; $x < $c; $x++) { //Populate the array
// ## Test each value ##########
$empty = $empty && (empty($csvData[$x]));
if ($specialChars === TRUE) {
$arrayCSV[$csvKey][$x] = htmlspecialchars($csvData[$x]);
} else {
$arrayCSV[$csvKey][$x] = $csvData[$x];
}
}
// ## Stop loop if all empty ##########
if ($empty) {
unset($arrayCSV[$csvKey]);
break;
}
$csvKey++;
}
fclose($csvHandle);
}
Note:
A blank line in a CSV file will be returned as an array comprising a single null field, and will not be treated as an error.
if ($c == 1 && current($csvData) === null) {
break;
}
You can run a extra loop for checking empty
while(! feof($file)){
$current_data = fgetcsv($file);
for ($i=0; $i < $total_title ; $i++) {
if( empty( $current_data[ $i ] ) ){
unset($information[$itt]);
break;
}
$information[$itt][ $titles[$i] ] = $current_data[$i] ;
}
$itt = $itt+1;
}
I recommend this php function that does exactly what you want
http://www.php.net/manual/es/function.file.php