xProteuSx Posted December 13, 2011 Share Posted December 13, 2011 I've been working on this too long, without having it figured out. Starting to get a bit 'kooky' at this point! I'm one stage away from retarded frustration. I have two arrays, such as these: Array 1 ( [0] => 7|1|0|5|0|0 [1] => 7|3|0|5|0|0 [3] => 7|4|0|5|0|0 [4] => 7|5|0|5|0|0 [5] => 7|6|0|5|0|0 [6] => 7|7|0|5|0|0 ) Array 2 ( [0] => 8|1|0|5|0|0 [1] => 7|2|0|5|0|0 [2] => 7|3|0|5|0|0 [3] => 7|4|0|5|0|0 ) I am trying to write a piece of code that will compare every value in array 2 to every value in array 1 and if the first 2 NUMERICAL values do not exist in Array 1, they are to be added to it. So, in the end, after comparison, Array 1 should look like this: Array 1 ( [0] => 7|1|0|5|0|0 [1] => 7|3|0|5|0|0 [3] => 7|4|0|5|0|0 [4] => 7|5|0|5|0|0 [5] => 7|6|0|5|0|0 [6] => 7|7|0|5|0|0 => [7] => 8|1|0|5|0|0 [8] => 7|2|0|5|0|0) The values 7|3|0|5|0|0 and 7|4|0|5|0|0 from Array 2 have not been added to Array 1 because 7|3... and 7|4... already exist in Array 1. So far, I've got something like this: $match = 0; foreach ($array1 as $data1) { foreach ($array2 as $data2) { if ($data1 == $data2) { $match = 1; break; } } if ($match != 1) { array_push($array1, $data2); } else {$match = 0;} } Where have I gone wrong? Quote Link to comment Share on other sites More sharing options...
xProteuSx Posted December 13, 2011 Author Share Posted December 13, 2011 Help, please! Quote Link to comment Share on other sites More sharing options...
xProteuSx Posted December 13, 2011 Author Share Posted December 13, 2011 Here's a piece of code you can just throw into a PHP file to test: $duplicates = 0; $match = 0; $old_chores_array = array('7|1|0|5|0|0', '7|2|0|5|0|0', '7|3|0|5|0|0', '7|4|0|5|0|0', '7|5|0|5|0|0', '7|6|0|5|0|0', '7|7|0|5|0|0'); $new_chores_array = array ('7|1|0|5|0|0', '7|2|0|5|0|0'); print_r($old_chores_array); echo '<br />'; foreach ($old_chores_array as $oldchore) { foreach ($new_chores_array as $newchore) { if ($oldchore == $newchore) { $match = 1; $duplicates++; break; } } if ($match != 1) { array_push($old_chores_array, $newchore); break; } else {$match = 0;} } print_r($old_chores_array); echo '<br />'; echo 'There were ' . $duplicates . ' duplicates.<br />'; The output should be: Array ( [0] => 7|1|0|5|0|0 [1] => 7|2|0|5|0|0 [2] => 7|3|0|5|0|0 [3] => 7|4|0|5|0|0 [4] => 7|5|0|5|0|0 [5] => 7|6|0|5|0|0 [6] => 7|7|0|5|0|0 ) Array ( [0] => 7|1|0|5|0|0 [1] => 7|2|0|5|0|0 [2] => 7|3|0|5|0|0 [3] => 7|4|0|5|0|0 [4] => 7|5|0|5|0|0 [5] => 7|6|0|5|0|0 [6] => 7|7|0|5|0|0 ) There were 2 duplicates. Instead I get: Array ( [0] => 7|1|0|5|0|0 [1] => 7|2|0|5|0|0 [2] => 7|3|0|5|0|0 [3] => 7|4|0|5|0|0 [4] => 7|5|0|5|0|0 [5] => 7|6|0|5|0|0 [6] => 7|7|0|5|0|0 ) Array ( [0] => 7|1|0|5|0|0 [1] => 7|2|0|5|0|0 [2] => 7|3|0|5|0|0 [3] => 7|4|0|5|0|0 [4] => 7|5|0|5|0|0 [5] => 7|6|0|5|0|0 [6] => 7|7|0|5|0|0 [7] => 7|7|0|5|0|0 ) There were 2 duplicates. There were 2 duplicates, but none of them should have been added to the array. Quote Link to comment Share on other sites More sharing options...
xProteuSx Posted December 13, 2011 Author Share Posted December 13, 2011 Updated code, because this is actually a multi-dimensional array: $duplicates = 0; $match = 0; $old_chores_array = array('7|1|0|5|0|0', '7|2|0|5|0|0', '7|3|0|5|0|0', '7|4|0|5|0|0', '7|5|0|5|0|0', '7|6|0|5|0|0', '7|7|0|5|0|0'); $new_chores_array = array ('7|1|0|5|0|0', '7|2|0|5|0|0'); print_r($old_chores_array); echo '<br />'; foreach ($old_chores_array as $oldchore) { foreach ($new_chores_array as $newchore) { $newchore = explode("|", $newchore); if (($oldchore[0] == $newchore[0]) && ($oldchore[1] == $newchore[1])) { $match = 1; $duplicates++; break; } } if ($match != 1) { $newchore = implode("|", $newchore); array_push($old_chores_array, $newchore); break; } else {$match = 0;} } print_r($old_chores_array); echo '<br />'; echo 'There were ' . $duplicates . ' duplicates.<br />'; Still get some silly output. To re-iterate: only indexes 0 and 1 of the inner-most array matter; these cannot be added to the old array. The output always points out the correct number of duplicates, but it ALWAYS adds the last array within Array2 to $old_chores_array, whether it is a duplicate or not. If you use the following array values: $old_chores_array = array('7|1|0|5|0|0', '7|2|0|5|0|0', '7|3|0|5|0|0', '7|4|0|5|0|0', '7|5|0|5|0|0', '7|6|0|5|0|0', '7|7|0|5|0|0'); $new_chores_array = array ('8|1|0|5|0|0', '8|2|0|5|0|0'); There are 0 duplicates, however only the last value of $new_chores_array is appended to $old_chores_array, but they both should be. I figure I have the array_push and/or break in the wrong place, but I just can't figure this one out. Quote Link to comment Share on other sites More sharing options...
xProteuSx Posted December 13, 2011 Author Share Posted December 13, 2011 Looks like I'll be working on this yet another day. Please guys (and gals)! I really can't get this; I need your help. Thanks in advance. Quote Link to comment Share on other sites More sharing options...
Drummin Posted December 13, 2011 Share Posted December 13, 2011 Give this a try. <?php $old_chores_array = array('7|1|0|5|0|0', '7|2|0|5|0|0', '7|3|0|5|0|0', '7|4|0|5|0|0', '7|5|0|5|0|0', '7|6|0|5|0|0', '7|7|0|5|0|0'); $new_chores_array = array ('7|1|0|5|0|0', '7|2|0|5|0|0', '7|2|0|2|1|0'); print_r($old_chores_array); echo '<br />'; foreach ($new_chores_array as $newchore) { if(!in_array($newchore,$old_chores_array)){ array_push($old_chores_array, $newchore); }} print_r($old_chores_array); echo '<br />'; ?> Quote Link to comment Share on other sites More sharing options...
xProteuSx Posted December 13, 2011 Author Share Posted December 13, 2011 Drummin, First, thank you for your reply. The problem with what you've provided me with is that data within $old_chores_array and $new_chores_array is all arrays as well, and must be compared solely by the first two numerical values, as separated by the | character. Hence: 7|1|0|5|0|0 = 7|1|0|5|3|0 = 7|1|0|10|0|0 and 7|1|0|5|0|0 != 8|1|0|5|0|0 != 7|11|0|5|0|0 Know what I mean? That's why I was originally using nested foreach loops. Quote Link to comment Share on other sites More sharing options...
xyph Posted December 13, 2011 Share Posted December 13, 2011 <?php $array1 = array( '1,2,3,4,5', '1,3,3,4,5', '1,4,3,4,5' ); $array2 = array( '1,1,3,4,5', '1,3,3,4,5', '1,5,3,4,5' ); $array1_firstTwo = array(); // Loop through array1, store the values of the first two digits in it's own array foreach( $array1 as $val ) { $check = substr( $val, 0, // Using a nested strpos will find the position of the second occurance // This will return the first two values strpos( $val,',',strpos($val,',')+1 ) ); // We then create a new key using that array, because isset() is much faster than in_array() $array1_firstTwo[ $check ] = TRUE; } // Loop through array2 foreach( $array2 as $val ) { $check = substr( $val, 0, strpos( $val,',',strpos($val,',')+1 ) ); // Check if the first two values exist in the array we jsut created if( !isset($array1_firstTwo[$check]) ) { // Add that value to $array1 $array1[] = $val; } } // Display array1 print_r( $array1 ); ?> Quote Link to comment Share on other sites More sharing options...
xProteuSx Posted December 13, 2011 Author Share Posted December 13, 2011 Wow ... I think its going to take a little bit of time to get my head around this one, but it seems to be working. Thank you very much. I won't pretend to understand this code at the moment, but I'll be sure to figure it out as I go. Again, thank you. I've never been stuck for so long before. Quote Link to comment Share on other sites More sharing options...
xyph Posted December 13, 2011 Share Posted December 13, 2011 The first challenge is that you only want the first TWO numbers to compare. Within that, the numbers could be anything, from one to one billion, so the actual positions of each number with in the string is variable. Thankfully, there's a delimiter we can search for within the string. I use strpos twice to get the 'offset' of the second delimiter. In your example, it's |. An offset in a string is simply a character position, starting at 0. In the string 'Hello World', the character at offset 0 is 'H', and the character at offset 8 is 'r'. Using offsets is a great tool in manipulating strings. So, let's look at strpos() and how we can use it in one of your examples to eventually extract the first two values. strpos() needs 2 arguments, and will take a third. The first is the 'haystack' - the string we want to search. The second is the 'needle' - the string we're searching for. The third would be an offset - where in the string to start the search. So, let's use a haystack of '12|4|23|54|200' $haystack = '12|4|23|54|200'; $needle = '|'; echo strpos( $haystack, $needle, 0 ); // Outputs 2 So, we now know that the first occurrence of $needle in $haystack is at offset 2. It's a good start, but we want to find the offset of the second occurrence so we can capture the first two values. If we change the starting offset of 0 to the offset of the first occurrence, it will give us the offset of the second occurrence! $haystack = '12|4|23|54|200'; $needle = '|'; $first = strpos( $haystack, $needle, 0 ); echo strpos( $haystack, $needle, $first ); // Outputs 2 Wait, shouldn't it output 4? Well, it starts the search at offset 2, which happens to be the $needle. To skip this, we have to add 1 to $first to start searching for the character AFTER the first $needle. So... $haystack = '12|4|23|54|200'; $needle = '|'; $first = strpos( $haystack, $needle, 0 ); echo strpos( $haystack, $needle, $first+1 ); // Outputs 4 That's more like it! In my function, I've simply combined the two into a single line. $haystack = '12|4|23|54|200'; $needle = '|'; echo strpos( $haystack, $needle, strpos($haystack,$needle)+1 ); // Outputs 4 We can get rid of the 0, because if the third argument is left out of strpos(), it is automatically 0. Now, we know the position of the second needle. All there is left to do is extract it. We can use substr for that. substr() needs 2 arguments, and will take a third. The first is the source string that you need to extract from. The second is the starting offset - where to start the extraction. The third is how many characters after the starting offset to capture. Since we want to grab the first two values, the starting offset will be 0 - that start of the string. To find out how many characters we need to capture, we simply subtract the starting offset (0) from the offset of the second $needle (4). Since 4-0 = 4, we can just plug in the offset of the second $needle. $haystack = '12|4|23|54|200'; $needle = '|'; $second = strpos( $haystack, $needle, strpos($haystack,$needle,0)+1 ); echo substr( $haystack, 0, $second ); // Outputs 12|4 And again, we can combine this into a single function call. $haystack = '12|4|23|54|200'; $needle = '|'; echo substr( $haystack, 0, strpos( $haystack, $needle, strpos($haystack,$needle,0)+1 ) ); // Outputs 12|4 Why put it in a single call? Since we aren't going to use this information again, there's no need to clutter up the script with single-use variables. This saves a little memory, and helps avoid 'variable clutter' Anything else you don't quite understand? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.