Name Count in foreach loop

7 posts by 3 authors in: Forums > CMS Builder
Last Post: September 13, 2017   (RSS)

By Mikey - September 10, 2017

I'm trying to count the total matching names inside of a foreach loop and produce a number that sits beside it's name. But all I get is a "Notice: Array to string conversion" message.

I need to count to totals for people's matching first names, and list them as seen below in the example. So if there's 24 people named John, the results displayed would read as "John: 24".

Example of what I'm trying to achieve:

John: 24
Tommy: 18
Victor: 12
Jane: 21
Janet: 13

<?php foreach ($namesCountRecords as $record): ?>
<?php
$results = array($record['first_name'].",");
$count = array();
    foreach ($results as $data){
       isset($count[$data]) ? $count[$data]++ : $count[$data] = 1;
     }
       echo htmlencode($record['first_name'].":"); echo $count;
?>
<?php endforeach ?>

Anyone have any suggestions?

Thanks, Zicky

By Mikey - September 11, 2017

Thanks to help of the thread below I was able to remove the duplicates from my foreach loop.

https://www.interactivetools.com/forum/forum-posts.php?postNum=2241105#post2241105

But I still can't figure out how to perform the total of each name in counting function.

Example of what I'm trying to achieve:

John: 24
Tommy: 18
Victor: 12
Jane: 21
Janet: 13

Example of what I'm getting, which is only counting a single instance of the first name and not all the Johns, Tommys, Victors, Janes, and Janets:

John: 1
Tommy: 1
Victor: 1
Jane: 1
Janet: 1

<?php $alreadyListed = []; ?>
<?php foreach ($namesCountRecords as $key => $record): ?>
    <?php if(!in_array(strtolower($record['first_name']), $alreadyListed)): ?>
        <?php echo $record['first_name'] ?>
        <?php $alreadyListed[] = strtolower($record['first_name']); ?>
            <?php $str = $record['first_name']; ?>
            <?php $key = count($str); ?>
            <?php print_r($key); ?><br>
    <?php endif; ?>
<?php endforeach ?>

Anyone have any suggestions on how to get this to work or a better way to remove duplicate names and still count the totals for person's similar each name?

Also, any suggestions on how to change <?php print_r($key); ?> to an <?php echo $key; ?> ? When I try this it breaks.

Thanks, Zicky

By Dave - September 11, 2017

Hi Zicky, 

How about this? 

  $firstNames    = array_column($namesCountRecords, 'first_name');
  $namesToCounts = array_count_values($firstNames);
  foreach ($namesToCounts as $firstName => $count) {
    print htmlencode($firstName) .": $count<br/>\n";   
  }

Let me know if that works for you!

Dave Edis - Senior Developer
interactivetools.com

By Mikey - September 11, 2017

Dave - Thank!!! You're the man!

Works like a charm and it's so clean.

By Mikey - September 12, 2017 - edited: September 12, 2017

I built a bar chart using Charts.js "http://www.chartjs.org" that displays people's first names and the total number of people with the same first name. Thought I'd share this for anyone else who may find it useful. You'll need to get a copy of Chart.js https://github.com/chartjs/Chart.js to make this work.

...and if you build any of your own charts, please share what you came up with.

Many thanks to Dave for the help getting the first names and counting worked out.

Below is the code, and I also attached a "Bar Chart" PHP file to this post.

Zicky

<?php header('Content-type: text/html; charset=utf-8'); ?>
<?php
  /* STEP 1: LOAD RECORDS - Copy this PHP code block near the TOP of your page */
  
  // load viewer library
  $libraryPath = 'cmsb/lib/viewer_functions.php';
  $dirsToCheck = array('/match/your/directory/','','../','../../','../../../');
  foreach ($dirsToCheck as $dir) { if (@include_once("$dir$libraryPath")) { break; }}
  if (!function_exists('getRecords')) { die("Couldn't load viewer library, check filepath in sourcecode."); }
    
  // load records from 'name'
  list($nameRecords, $nameMetaData) = getRecords(array(
    'tableName'   => 'name',
    'loadUploads' => true,
    'allowSearch' => false,
  ));

?>

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Bar Chart</title>

<style type="text/css">
    #myChart {
        margin:0 auto;
        width:90%;
        height:inherit;
    }
</style>

<script src="js/Chart.2.6.0.bundle.js"></script>
<script src="js/utils.js"></script>

</head>

<body>

<canvas id="myChart"></canvas>

<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: [
            <?php
                $pagenames    = array_column($nameRecords, 'first_name');
                $namesToCounts = array_count_values($pagenames);
                    foreach ($namesToCounts as $pagename => $count) {
                    print ('"'.$pagename.'",');
            } ?>
                ],
                
        datasets: [{
            label: 'Most Used Names',
            data: [
                <?php
                    $pagenames    = array_column($nameRecords, 'first_name');
                    $namesToCounts = array_count_values($pagenames);
                        foreach ($namesToCounts as $pagename => $count) {
                        print htmlencode($count.',');
                } ?>
                  ],
                
            backgroundColor: [
                    <?php foreach ($nameRecords as $record): ?>
                        <?php { $r = rand(0,255); $g = rand(0,255); $b = rand(0,255); $opacity = 0.4; } ?>
                        '<?php echo "rgba(".$r.",".$g.",".$b.",".$opacity.")"; ?>',
                    <?php endforeach ?>
                             ],
                    
            borderColor: [
                            'rgba(0, 0, 0, 0.4)',
                        ],
                        
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                }
            }]
        }
    }
});
</script>

</body>
</html>

Attachments:

bar-chart.php 3K

By Mikey - September 13, 2017

Glad you found it useful. I'll post up any other charts I build as well. Got a few others in mind I plan to build.

Cheers, Zicky