Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to order my array. My first array will have values string values few of them will be same now i want to know how many of each value is there and add that to a new array as key and value the number of how many times it appears in first array now i get to do this yet i get a bug.

Last entry instead of being counter in gets added extra.

I tried while/for/foereach same result.

Code:

<?php
 function add_fit($fitting)
   {
        // Save raw fit
        $eft = $fitting;

        // Clean for import
        $fit = trim($fitting);
        $lines = explode("\n", $fit);
        $lines = array_filter($lines, 'trim');

        // Split first line for name and type
        $details = str_replace('[', '', $lines[0]);
        $details = str_replace(']', '', $details);
        $split_details = explode(', ', $details);

        $ship = $split_details[0];
        $name = $split_details[1];

        foreach ($lines as $line => $module) {
            if(strstr($module, '[empty '))
            {
                unset($lines[$line]);
            }
        }

        $all = array();
        foreach ($lines as $index => $segment) {
            array_push($all, $segment);
        }

        $modules = array();
        for($i = 1; $i < count($all); $i++)
        {
            if(isset($modules[$all[$i]]))
            {
                $modules[$all[$i]] = $modules[$all[$i]]+1;
            } else {
                $modules[$all[$i]] = 1;
            }
        }

        var_dump($modules);

   }

/*
The $fitting is as follows:

[Thrasher, Buffer Thrasher]
Gyrostabilizer II
Gyrostabilizer II

Small F-S9 Regolith Shield Induction
Small F-S9 Regolith Shield Induction
1MN MicroWarpdrive I

280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
[empty high slot]

Small Ancillary Current Router I
Small Ancillary Current Router I
Small Ancillary Current Router I


And the method returns:
  'Gyrostabilizer II'                    => int 2
  'Small F-S9 Regolith Shield Induction' => int 2
  '1MN MicroWarpdrive I'                 => int 1
  '280mm Howitzer Artillery II'          => int 7
  'Small Ancillary Current Router I'     => int 2
  'Small Ancillary Current Router I'     => int 1


While it should return:
  'Gyrostabilizer II'                    => int 2
  'Small F-S9 Regolith Shield Induction' => int 2
  '1MN MicroWarpdrive I'                 => int 1
  '280mm Howitzer Artillery II'          => int 7
  'Small Ancillary Current Router I'     => int 3   <-- Like this
*/

?>
share|improve this question
4  
Your first sentence makes no sense..how about a bit of punctuation? –  vascowhite Sep 27 '12 at 22:07
    
A fitting mod for EDK? –  vascowhite Sep 27 '12 at 22:08
    
No a seperate standalone app. Also i need a copy of the argument to be passed on later. –  kellax Sep 27 '12 at 22:47
add comment

2 Answers

You must have some non-printing characters in your input, as a hash can't have the same key with multiple values (which is what your output shows - two keys of Small Ancillary Current Router I, which must be different as they have different values . . . )

What's a var_dump(array_keys($modules)) show?

Solution is to better sanitize your input - looks like you should probably add something in your cleanup section . . . maybe something like this to strip UTF, or if that's the last line in your input, there may be an EOF character in there . . .

Edit: From your comments, the var_dump output is:

5 => string 'Small Ancillary Current Router I' (length=33) 
6 => string 'Small Ancillary Current Router I' (length=32)

Note that one is 33 and the other is 32, meaning a non-printing character is causing differences. A shotgun approach to removing all non-printing characters is described here. To implement in your code:

    $all = array();
    foreach ($lines as $segment) {
        $all[] = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $segment);
    }
share|improve this answer
    
Tried but still the same problem. –  kellax Sep 27 '12 at 22:57
    
What's a var_dump(array_keys($modules)) show? –  ernie Sep 27 '12 at 23:27
    
5 => string 'Small Ancillary Current Router I' (length=33) 6 => string 'Small Ancillary Current Router I' (length=32) They are diffirent lengths im asuming there are non printable chars in former but i cant remove them any way i try str replace, trim, perg_match etc. –  kellax Sep 27 '12 at 23:31
    
What's your trim function that you're using as the callback in array_filter look like? –  ernie Sep 27 '12 at 23:33
    
It just calls trim again to remove any extra \r characters left behind. –  kellax Sep 27 '12 at 23:36
show 2 more comments

You should probably be using array_key_exists() rather than isset. The reason can be seen in this SO question

Either way you have some whitespace causing the problem. Try adding a trim to the following line and it should work:

foreach ($lines as $index => $segment) { 
    array_push($all, $segment); 
} 

Change to:

foreach ($lines as $index => $segment) { 
    array_push($all, trim($segment)); 
} 

And BTW: o7 fly safe ;-)

UPDATE: heres the code I used for testing:

<!DOCTYPE html>
<html>

<head>
</head>
<body>
<?php 

$whatever = "[Thrasher, Buffer Thrasher] 
Gyrostabilizer II 
Gyrostabilizer II 

Small F-S9 Regolith Shield Induction 
Small F-S9 Regolith Shield Induction 
1MN MicroWarpdrive I 

280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
[empty high slot] 

Small Ancillary Current Router I 
Small Ancillary Current Router I 
Small Ancillary Current Router I";

echo '<pre>';
print_r(add_fit($whatever));
echo '</pre>';


 function add_fit($fitting) 
   { 
        // Save raw fit 
        $eft = $fitting; 

        // Clean for import 
        $fit = trim($fitting); 
        $lines = explode("\n", $fit); 
        $lines = array_filter($lines, 'trim'); 

        // Split first line for name and type 
        $details = str_replace('[', '', $lines[0]); 
        $details = str_replace(']', '', $details); 
        $split_details = explode(', ', $details); 

        $ship = $split_details[0]; 
        $name = $split_details[1]; 

        foreach ($lines as $line => $module) { 
            if(strstr($module, '[empty ')) 
            { 
                unset($lines[$line]); 
            } 
        } 

        $all = array(); 
        foreach ($lines as $index => $segment) { 
            array_push($all, trim($segment)); 
        } 

        $modules = array(); 
        for($i = 1; $i < count($all); $i++) 
        { 
            if(isset($modules[$all[$i]])) 
            { 
                $modules[$all[$i]] = $modules[$all[$i]]+1; 
            } else { 
                $modules[$all[$i]] = 1; 
            } 
        } 

        return $modules; 

   } 

?>
</body>
</html>
share|improve this answer
    
Hey mate i tried array_key_exists() and triming the $segment but thats not it the first two modules in last key are 33 in length while the last module is 32 in length yet they show everything the same. Weird tho i trimed away all \r and \n. Also fly safe o7 –  kellax Sep 27 '12 at 22:55
    
@kellax: I tried your code in my test bed and adding the trim fixed the output the way you wanted. Not sure what could be different in your setup apart from an encoding issue/difference. You using apache, IIS, etc? And what version of PHP? –  Zappa Sep 27 '12 at 22:58
    
Im using WAMP with PHP 5.4.3, page encoding is set to utf8 i also tried preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $segment) When i do a var_dump on the $modules array i get the last key's length 32 and one before it 33 so there is a non printable char somewhere not getting removed. –  kellax Sep 27 '12 at 23:04
    
Also I assumed that the input $fitting value was a string. –  Zappa Sep 27 '12 at 23:04
    
$fitting is direct $_POST from a <textarea> content –  kellax Sep 27 '12 at 23:06
show 6 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.