0

I am using laravel, I am getting this error when trying to count the valuse of this array.

Error:array_count_values(): Can only count STRING and INTEGER values!

the function:

public function test()
{
  $test = \DB::table('surveys')->where('company_id', '=', 1)->select('rd1')->get()->toArray();;
  $c = array_count_values($test);
  $val = array_search(max($c), $c);
  return view ('companies.test', compact('val'));

}

here is a var_dump of $test:

  array:4 [▼
  0 => {#204 ▼
    +"rd1": "option1"
  }
  1 => {#206 ▼
    +"rd1": "option1"
  }
  2 => {#207 ▼
    +"rd1": "option1"
  }
  3 => {#208 ▼
    +"rd1": "option1"
  }
]
Jonathan Kuhn
  • 15,279
  • 3
  • 32
  • 43
Sara M.
  • 35
  • 1
  • 1
  • 7
  • 1
    what is the output of `var_dump($test)` ? – georoot Dec 08 '16 at 21:43
  • Looks like you want `count`, not `array_count_values`. `array_count_values` will loop over an array and key a count of how many times a value exists in an array. So an array like `[1, 2, 3, 1]` would return `[1=>2, 2=>1, 3=>1]` meaning that value `1` exists `2` times in the array..etc. `count` will return just the number of rows in the array, which with the example is `4`. – Jonathan Kuhn Dec 08 '16 at 21:47
  • it says it all, if the elements of the array aren't string or numbers you can't count their frequency using this function. – sidyll Dec 08 '16 at 21:47
  • just upated it now – Sara M. Dec 08 '16 at 21:48
  • what i want is to know what is the most frequent value in the array – Sara M. Dec 08 '16 at 21:52
  • This var_dump is a bit strange in its formatting to me. What are the elements of the array? Objects? Other arrays? – sidyll Dec 08 '16 at 21:53
  • Well, this is a 2d array, which is why array_count_values would return an error saying the value can't be an array. You would have to use array_count_values in combination with array_column which would turn it back into a 1d array of just the value you want which you could count the values. `array_count_values(array_column($test, $columnName))`. That or make your own array_count_values that accepts a column to look under in the case of a 2d array. – Jonathan Kuhn Dec 08 '16 at 21:55
  • it extracting a coulmn from a table called survey, the survey is a model class – Sara M. Dec 08 '16 at 21:55
  • 2
    You should be able to do this in your query with group by and count. – Don't Panic Dec 08 '16 at 21:59
  • Thanks Jonathan it is working now! – Sara M. Dec 08 '16 at 22:01
  • 1
    Have a look at this question for a better method like @Don'tPanic is suggesting: http://stackoverflow.com/questions/18533080/laravel-eloquent-groupby-and-also-return-count-of-each-group – Jonathan Kuhn Dec 08 '16 at 22:03

2 Answers2

0

The built-in function array_count_values() can't calculate the frequency if the elements are not strings or numbers. You can, however, easily perform a loop to do so:

foreach ($array as $e)
    $frequency[$e] =+ 1;

This would basically do the same as the built-in. Note that the elements are used as keys for the final frequency array (and you can imagina that if $e is not a valid key (string or number) it will fail). In your case, you need to use as key a property of your element. For example, if it is another array:

foreach ($test as $e)
    $frequency[$e['survey_name']] += 1;

Or properties/methods of an object:

foreach ($test as $e)
    $frequency[$e->myColumn()] += 1;
sidyll
  • 57,726
  • 14
  • 108
  • 151
0

Your array is 2d which array_count_values doesn't like. You can either perform a loop and count the values yourself, or use something like array_column to get an array of the value from just the one column. Example:

array_count_values(array_column($test, $columnName))

array_column will get an array of values from just the one column you specify, which in your case is a string and that returned array can be passed to array_count_values to get the result you want.

Of course though, as someone else commented, this grouping and counting can be done by the database much more efficiently (you would be passing back less data and the database can be optimized to return queries like this with indexes). Here is another question that covers this.

You could then turn that back into a similar array with just array_column like:

\DB::table('surveys')
    ->where('company_id', '=', 1)
    ->select('rd1', \DB::raw('count(*) as total')
    ->groupBy('rd1')
    ->get()
    ->toArray();;
array_column($test, 'total', 'rd1');
Community
  • 1
  • 1
Jonathan Kuhn
  • 15,279
  • 3
  • 32
  • 43