2

I want to get the count of country records in a multidimensional array. I also would like to get the same count, but filtered by the record, so count of the Netherlands.

I've tried this:

$total = array_sum(array_map("count", $data));
echo "total: " . $total;

It counts the number of records in the array.

I've tried:

$element = 'institutionID';
$count = array_count_values(array_column($data, 'institutionID'))[$element];
echo $count;

But nothing is returned. How do I do this?

data example

Array
(
    [0] => Array
        (
            [higherGeographyID] => http://vocab.getty.edu/tgn/7016845
            [higherGeography] => None
            [continent] => Europe
            [waterBody] => None
            [islandGroup] => None
            [island] => None
            [country] => The Netherlands
            [countryCode] => NL
            [stateProvince] => Groningen
            [county] => Groningen
            [municipality] => Groningen
            [locality] => Groningen
            [verbatimLocality] => None
            [minimumElevationInMeters] => None
            [maximumElevationInMeters] => None
            [verbatimElevation] => None
            [minimumDepthInMeters] => None
            [maximumDepthInMeters] => None
            [verbatimDepth] => None
            [minimumDistanceAboveSurfaceInMeters] => None
            [maximumDistanceAboveSurfaceInMeters] => None
            [locationAccordingTo] => None
            [locationRemarks] => None
            [decimalLatitude] => None
            [decimalLongitude] => None
            [geodeticDatum] => None
            [coordinateUncertaintyInMeters] => None
            [coordinatePrecision] => None
            [pointRadiusSpatialFit] => None
            [verbatimCoordinates] => None
            [verbatimLatitude] => None
            [verbatimLongitude] => None
            [verbatimCoordinateSystem] => None
            [verbatimSRS] => None
            [footprintWKT] => None
            [footprintSRS] => None
            [footprintSpatialFit] => None
            [georeferencedBy] => None
            [georeferencedDate] => None
            [georeferenceProtocol] => None
            [georeferenceSources] => None
            [georeferenceVerificationStatus] => None
            [georeferenceRemarks] => None
          
        )

    [1] => Array
        (
            ...
9
  • You want to count the number of occurrences of the country key, no matter how deep? Commented Jan 16, 2021 at 1:19
  • 2
    If you could revise your "data example" to include some white-space hierarchy would be helpful, indentation Commented Jan 16, 2021 at 1:21
  • @GetSet yes, no matter how deep, although it will always be at this level. Commented Jan 16, 2021 at 1:44
  • @GetSet white space added to make the same data more human readable. Commented Jan 16, 2021 at 1:49
  • Ok. How is country delimited? That is, what "data structure" or "format" do you have for country? Can it be more than one value in that field? It might seem like a filler question but am wondering why you just don't loop through and increment a cnt var when that array key exists? Commented Jan 16, 2021 at 2:29

3 Answers 3

3

Count of country records:

$dataCountry = array_column($data, 'country');
echo "total: ", count($dataCountry);

Count of The Netherlands:

$dataCountryCount = array_count_values(array_filter($dataCountry));
echo $dataCountryCount['The Netherlands'] ?? 0;

Multiple search filter:

$filter = ['country' => 'The Netherlands', 'continent' => 'Europe'];
$dataFilter = array_filter($data, function($item) use ($filter) {
    return $filter == array_intersect_key($item, $filter);
});
echo 'total:', count($dataFilter);

print_r($dataFilter);
Sign up to request clarification or add additional context in comments.

4 Comments

This would only count correctly if 'country' is one the first level of the array and I don't think that is what OP expected.
@bestprogrammerintheworld and yet it seems to work... I'll do some manual calculations to check its behaviour... any way to add in a second filter like continent['Europe']? I'm still getting my head around php after returning from python (django).
@SpatialDigger, added an example of multiple search filter.
@SpatialDigger - yes it would work based on your example but if you another level down (with country) in your arrays it would not.
0

You can try this below:

  $data = json_decode($data_json,true);

  echo count_filtered_by($data);
  // Returns (int) 3
  echo count_filtered_by($data,'country');
  // Returns (int) 3
  echo count_filtered_by($data,'country','The Netherlands');
  // Retruns (int) 2
  echo count_filtered_by($data,'country','UK');
  // Returns (int) 1
  echo count_filtered_by($data,'country','uK',true);
  // Returns (int) 0

  /**
  * Count filtered by
  * 
  * @param array $data
  * @param string|nullable $key
  * @param string|nullable $value
  * @param bool $strict Default is (Case Insensitive)
  * 
  * @return int count filtered by
  */
  function count_filtered_by($data,$key = NULL,$value = NULL,$strict = false) {
    $column = array_column($data,$key);
    if($key === NULL) return count($data);
    if($value === NULL ) return count($column);
    // Remove empty values
    $filtered = array_filter($column);

    $count = 0;
    foreach($filtered as $column) {
      if(!$strict) {
        $column = strtolower($column);
        $value = strtolower($value);
      }
      if($column === $value) $count++;
    }

    return $count;
  }

So I test your data here

  $data_json = '[
      {
          "higherGeographyID": "http:\/\/vocab.getty.edu\/tgn\/7016845",
          "higherGeography": "None",
          "continent": "Europe",
          "waterBody": "None",
          "islandGroup": "None",
          "island": "None",
          "country": "The Netherlands",
          "countryCode": "NL",
          "stateProvince": "Groningen",
          "county": "Groningen",
          "municipality": "Groningen",
          "locality": "Groningen",
          "verbatimLocality": "None",
          "minimumElevationInMeters": "None",
          "maximumElevationInMeters": "None",
          "verbatimElevation": "None",
          "minimumDepthInMeters": "None",
          "maximumDepthInMeters": "None",
          "verbatimDepth": "None",
          "minimumDistanceAboveSurfaceInMeters": "None",
          "maximumDistanceAboveSurfaceInMeters": "None",
          "locationAccordingTo": "None",
          "locationRemarks": "None",
          "decimalLatitude": "None",
          "decimalLongitude": "None",
          "geodeticDatum": "None",
          "coordinateUncertaintyInMeters": "None",
          "coordinatePrecision": "None",
          "pointRadiusSpatialFit": "None",
          "verbatimCoordinates": "None",
          "verbatimLatitude": "None",
          "verbatimLongitude": "None",
          "verbatimCoordinateSystem": "None",
          "verbatimSRS": "None",
          "footprintWKT": "None",
          "footprintSRS": "None",
          "footprintSpatialFit": "None",
          "georeferencedBy": "None",
          "georeferencedDate": "None",
          "georeferenceProtocol": "None",
          "georeferenceSources": "None",
          "georeferenceVerificationStatus": "None"
      },
      {
          "higherGeographyID": "http:\/\/vocab.getty.edu\/tgn\/7016845",
          "higherGeography": "None",
          "continent": "Europe",
          "waterBody": "None",
          "islandGroup": "None",
          "island": "None",
          "country": "The Netherlands",
          "countryCode": "NL",
          "stateProvince": "Groningen",
          "county": "Groningen",
          "municipality": "Groningen",
          "locality": "Groningen",
          "verbatimLocality": "None",
          "minimumElevationInMeters": "None",
          "maximumElevationInMeters": "None",
          "verbatimElevation": "None",
          "minimumDepthInMeters": "None",
          "maximumDepthInMeters": "None",
          "verbatimDepth": "None",
          "minimumDistanceAboveSurfaceInMeters": "None",
          "maximumDistanceAboveSurfaceInMeters": "None",
          "locationAccordingTo": "None",
          "locationRemarks": "None",
          "decimalLatitude": "None",
          "decimalLongitude": "None",
          "geodeticDatum": "None",
          "coordinateUncertaintyInMeters": "None",
          "coordinatePrecision": "None",
          "pointRadiusSpatialFit": "None",
          "verbatimCoordinates": "None",
          "verbatimLatitude": "None",
          "verbatimLongitude": "None",
          "verbatimCoordinateSystem": "None",
          "verbatimSRS": "None",
          "footprintWKT": "None",
          "footprintSRS": "None",
          "footprintSpatialFit": "None",
          "georeferencedBy": "None",
          "georeferencedDate": "None",
          "georeferenceProtocol": "None",
          "georeferenceSources": "None",
          "georeferenceVerificationStatus": "None"
      },
      {
          "higherGeographyID": "http:\/\/vocab.getty.edu\/tgn\/7016845",
          "higherGeography": "None",
          "continent": "Europe",
          "waterBody": "None",
          "islandGroup": "None",
          "island": "None",
          "country": "UK",
          "countryCode": "UK",
          "stateProvince": "Groningen",
          "county": "Groningen",
          "municipality": "Groningen",
          "locality": "Groningen",
          "verbatimLocality": "None",
          "minimumElevationInMeters": "None",
          "maximumElevationInMeters": "None",
          "verbatimElevation": "None",
          "minimumDepthInMeters": "None",
          "maximumDepthInMeters": "None",
          "verbatimDepth": "None",
          "minimumDistanceAboveSurfaceInMeters": "None",
          "maximumDistanceAboveSurfaceInMeters": "None",
          "locationAccordingTo": "None",
          "locationRemarks": "None",
          "decimalLatitude": "None",
          "decimalLongitude": "None",
          "geodeticDatum": "None",
          "coordinateUncertaintyInMeters": "None",
          "coordinatePrecision": "None",
          "pointRadiusSpatialFit": "None",
          "verbatimCoordinates": "None",
          "verbatimLatitude": "None",
          "verbatimLongitude": "None",
          "verbatimCoordinateSystem": "None",
          "verbatimSRS": "None",
          "footprintWKT": "None",
          "footprintSRS": "None",
          "footprintSpatialFit": "None",
          "georeferencedBy": "None",
          "georeferencedDate": "None",
          "georeferenceProtocol": "None",
          "georeferenceSources": "None",
          "georeferenceVerificationStatus": "None"
      }
  ]';

Comments

0

If I understood you correctly you could do this:

//Example data for testing
$arr = [
    ['a'=> ['country' => 'Netherland']],
    ['e'=> ['country' => 'Netherland']],
    ['b'=> ['country' => 'Sweden']],
    ['c'=> ['country' => 'Netherland'], 'a' => ['country' => 'Netherland']],
    ['f'=> ['country' => 'Sweden']],
];

//Init som global variables 
$count_countries = 0; //Number of occurences of 'country'
$check_country = 'Netherland'; //What country to check
$count_country = 0; //Number of occurences for chosen country to check

//Walk through array recursively and count each found occurence of 
//country and the actual country to check
array_walk_recursive($arr, function($item, $key) {
    global $count_countries, $count_country, $check_country;
    if ($key == 'country') $count_countries++;
    if ($item == $check_country) $count_country++;
});

//Output result
echo 'count for ' . $check_country . ' = ' . $count_country . '<br>';
echo 'count for countries = ' . $count_countries;

Result in this case:

count for Netherland = 4
count for countries = 6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.