Jump to content

Combine 2 Arrays Without Duplicates


xProteuSx

Recommended Posts

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 />';
?> 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

<?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 );

?>

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.