4

I'm trying to add 4 arrays into one array ($all_prices) and then check the values of each key in each individual array against $all_prices to make sure that they are unique. If they are not I want to add a 0 to the end of if to make it unique (so 0.50 becomes 0.500).

For some reason I'm getting the following error, despite the fact that I already changed the data type from decimal to varchar:

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

Edit Here is a snippet from dd($all_prices)

array(4) { [0]=> array(9) { ["14.45"]=> string(8) "sample 1" ["12.40"]=> 
string(8) "sample 2" ["14.13"]=> string(8) "sample 3" ["15.11"]=> 
string(8) "sample 4"

Code:

$all_prices   = [$list_a_prices, $list_b_prices, $list_c_prices, $list_d_prices];
$price_count  = array_count_values($all_prices);

foreach($list_b_prices as $key => $value){
    if($price_count[$key] >= 2){
        $key . "0";
    }
}

Where am I going wrong? Is there is a way to leave the data type as Decimal?

7
  • 2
    Can you edit the question to include the output of var_dump($all_prices);? Commented Jun 11, 2014 at 15:28
  • It just keeps going but I put a snippet to give you an idea, thanks. Commented Jun 11, 2014 at 15:32
  • I notice that it doesn't say "string" for the prices, but I set the database table to save the price as a Varchar, so it should be a string right? Or do I need to do something else as well? Commented Jun 11, 2014 at 15:33
  • 1
    Nope, that wouldn't change anything. array_count_values() requires a single-dimensional array, but you're supplying a 2-dimensional array. The function can't search inside arrays — you need to flatten the array first. So create a new array containing all the values you need, and then apply the function, and it should work. Commented Jun 11, 2014 at 15:38
  • AHHHH, so something like $all_prices = []+$list_a_prices+... etch would work? Commented Jun 11, 2014 at 15:39

2 Answers 2

1

I think you should not index by the prices, after all from a math point of view 5.0 and 5.00 does not make difference at all.

If you are obtaining values from a database you will get strigs everywhere. So you will have to cast (int)$key for the keys.

And in your foreach you are changing a temporary variable. $key exists only for the current iteration of the loop you will want to declare it as:

foreach($list_b_prices as &(int)$key => $value){
    if($price_count[$key] >= 2){
        $key . "0";
    }
}

Note the ampersand and the casting to integer. Although i'm not sure which will come first. But again: I think indexing by some different value shall give you a better result.

Sign up to request clarification or add additional context in comments.

8 Comments

No, that would simply not work. You can't do &(int)$key — it will result in a syntax error. Plus, this doesn't solve the problem here; array_count_values() requires a single-dimensional array with scalar values in it, and currently the OP's array contains other arrays.
Yeah, you're probably right, I'm not quite sure about his end goals, but if you want unique keys indexing by prices, well not a good idea. That's why I am suggesting choosing a different index in first place.
Well I used $all_prices = []+$list_a_prices+... and plugged it into array_count_values and got a normal looking response. So at least that part worked.
Could you rather tell us what is it you trying to do? Sort by prices?
Amal shall definatley have a solution for you on the chat, but if I were doing that I would set an array for each price, not a string. The array can contain multiple items with the same price. Simply adding 0 digits at the end, will get even more a hassle with adding in items.
|
1

What about a nested loop ?

$all_prices   = [$list_a_prices, $list_c_prices, $list_d_prices];

foreach($list_b_prices as $key => $value){
    foreach($all_prices as $array){
        if(isset($array[$key])){
            $list_b_prices[$key] .= '0';
        }
    }
}

Not elegant but it does the trick.

14 Comments

I'm not sure I understood, but I just noticed that the code I posted contains a bug : it will compare the values of $list_b_prices against themselves at the second second foreach iteration, appending 0s to all of its elements. To fix this, you can either exclude $list_b_prices from $all_prices or add a === check inside the second loop. I'll edit it right away.
To try and answer your question : if there are three similar prices in $list_a_prices, $list_b_prices and $list_d_prices, the code will check against the one in $list_a_prices first and append a 0 to the value that is inside $list_b_prices. When the (second) loop gets to $list_d_prices, the conflicting value will already have been modified by the previous iteration, so the isset will return false.
Within the same array ? In the var_dump you posted, the prices are the keys so if there were two similar prices, one of them would overwrite the other before it even gets to the loop. I'm starting to get the feeling that this solution getting unnecessary complex, maybe there is a better way to approach the problem ?
Are the samples guaranteed to have different names in the $list_x_prices arrays ? If so, maybe you can use them as keys instead of the prices, that would eliminate the problem of having to deal with duplicate keys.
Not exactly what I had in mind, but it's interesting. I was gonna suggest passing them to the drop down menu with the names as keys and the prices as values, then modify the... ah this is confusing. What does the drop down menu look like though ? Are the prices displayed inside the option attribute or is it the names ?
|

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.