Hi there folks!

TL;DR for anyone that doesn't need my verbosity:

array_splice( $sim_array, 0, 0, $match_array);

seems to be ruining the multidimensional nature of the inserted element($match_array).

------------------Full meal deal follows---------------------

I'm trying to build a "similar content" feature on my site and the way I've decided to handle it is to store the top 10 id's and scores for a given row and when it's time to check for new and better matching content, it does the following:

1) Store the current top 10 results in an array

2) loop through new content, score it and then insert into the current array in it's proper location (if it beats the score of the current 3rd slot, place it in that location, shifting 4 - 10th down).

3) Trim the array back to 10 results so I can create an update clause.

Here's what my array looks like before I fiddle with it:

Array
(
    [0] => Array
        (
            [0] => 0
            [1] => 0
        )

[1] => Array
    (
        [0] => 0
        [1] => 0
    )

[2] => Array
    (
        [0] => 0
        [1] => 0
    )

[3] => Array
    (
        [0] => 0
        [1] => 0
    )

[4] => Array
    (
        [0] => 0
        [1] => 0
    )
... shortened

All the 0's are because my system isn't working yet.

Next, I create an array for the new content's ID and score for later check and insertion:

Array
(
    [0] => 1
    [1] => 9
)

I then have an elseif dance to see where it needs to place the new string into the array:

		if($match_score > $sim1score){
			array_splice( $sim_array, 0, 0, $match_array);
		}elseif($match_score > $sim2score){
			array_splice( $sim_array, 1, 0, $match_array);
		}elseif($match_score > $sim3score){
			array_splice( $sim_array, 2, 0, $match_array);
		}elseif($match_score > $sim4score){
			array_splice( $sim_array, 3, 0, $match_array);
		}elseif($match_score > $sim5score){
			array_splice( $sim_array, 4, 0, $match_array);
		}elseif($match_score > $sim6score){
			array_splice( $sim_array, 5, 0, $match_array);
		}elseif($match_score > $sim7score){
			array_splice( $sim_array, 6, 0, $match_array);
		}elseif($match_score > $sim8score){
			array_splice( $sim_array, 7, 0, $match_array);
		}elseif($match_score > $sim9score){
			array_splice( $sim_array, 8, 0, $match_array);
		}elseif($match_score > $sim10score){
			array_splice( $sim_array, 9, 0, $match_array);
		}

Then trim it back to 10 results:

$sim_array = array_slice($sim_array, 0, 10);

So, my hope with array_splice in this example would have been to have it insert the multidimensional string in the first place and it did, kind of. The problem seems to be that it ruined it's multidimensional nature. Here's what my array looks like after my splice attempt:

Array
(
    [0] => 1
    [1] => 9
    [2] => Array
        (
            [0] => 0
            [1] => 0
        )

[3] => Array
    (
        [0] => 0
        [1] => 0
    )

[4] => Array
    (
        [0] => 0
        [1] => 0
    )
... shortened

Could someone help me figure out how to insert new elements into an array in the proper location without losing the proper multidimensional nature?

array_splice( $sim_array, 0, 0, $match_array);

seems to be ruining the inserted element's format.

    I think this little change might fix it for you:

    array_splice($sim_array, 0, 0, array($match_array));
    

      We've got lots of array functions that should help. Does this shed any light? I think it might work for ya.

      <?php
      
      //construct an array
      
      $n = 0;
      
      $arr = array();
      
      while ($x < 11 ) {
      
         $arr[$x]=array($n, ++$n);
         $x++;
      }
      
      
      // Here's what you need...
      
      $chunk = array_chunk($arr,5);
      
      $new[1] = array(155,255);
      
      $out_array = array_merge($chunk[0],$new,$chunk[1]);
      
      array_pop($out_array);
      
      print_r($out_array);
      

      EDIT: Nog's answer's probably better 😉

        I also considered the idea of just adding the new sub-array anywhere ([] notation or array_push()), then using usort() or such to sort it into the desired order; but then decided to just go with the simple change (assuming it works). 🙂

          Hi there guys and thanks very much for your help!

          My issue has migrated some and I'm sure it's caused by me not being clever enough but I can't see what I've done wrong.

          My intention is to end up with an array sorted by score in descending order. My code works for 3 or 4 loops and then falls apart, placing things out of order.

          Here's my current code:

          My initial array:

          	$sim_array = array(
          		array($sim1id,$sim1score),
          		array($sim2id,$sim2score),
          		array($sim3id,$sim3score),
          		array($sim4id,$sim4score),
          		array($sim5id,$sim5score),
          		array($sim6id,$sim6score),
          		array($sim7id,$sim7score),
          		array($sim8id,$sim8score),
          		array($sim9id,$sim9score),
          		array($sim10id,$sim10score)
          	);

          And inside my loop where I check the new content:

          if($match_score > $sim1score){
          
          		array_splice($sim_array, 0, 0, array($match_array));
          		$sim1score = $match_score;
          		$simstop = '1';
          		echo 1;
          	}elseif($match_score > $sim2score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 1, 0, array($match_array));
          		$sim2score = $match_score;
          		$simstop = '1';
          		echo 2;
          	}elseif($match_score > $sim3score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 2, 0, array($match_array));
          		$sim3score = $match_score;
          		$simstop = '1';
          		echo 3;
          	}elseif($match_score > $sim4score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 3, 0, array($match_array));
          		$sim4score = $match_score;
          		$simstop = '1';
          		echo 4;
          	}elseif($match_score > $sim5score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 4, 0, array($match_array));
          		$sim5score = $match_score;
          		$simstop = '1';
          		echo 5;
          	}elseif($match_score > $sim6score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 5, 0, array($match_array));
          		$sim6score = $match_score;
          		$simstop = '1';
          		echo 6;
          	}elseif($match_score > $sim7score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 6, 0, array($match_array));
          		$sim7score = $match_score;
          		$simstop = '1';
          		echo 7;
          	}elseif($match_score > $sim8score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 7, 0, array($match_array));
          		$sim8score = $match_score;
          		$simstop = '1';
          		echo 8;
          	}elseif($match_score > $sim9score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 8, 0, array($match_array));
          		$sim9score = $match_score;
          		$simstop = '1';
          		echo 9;
          	}elseif($match_score > $sim10score AND !ISSET($simstop)){
          
          		array_splice($sim_array, 9, 0, array($match_array));
          		$sim10score = $match_score;
          		$simstop = '1';
          		echo 10;
          	}
          	UNSET($simstop);
          	echo ' triggered by '.$match_score.'<br>';
          	print_r($sim_array);
          }
          
          /* Trim the results array back to 10 entries */
          $sim_array = array_slice($sim_array, 0, 10);
          print_r($sim_array);

          You can see in my loop that I check which else is triggered and then print the array to see what changes were made to it. This works well until it gets to the score of 17 and it all begins to fall apart. I have trimmed the tails of the arrays for brevity.

          Look for the line 4 triggered by 17<br>Array and you can see where it placed it into the array between scores 23 and 20 instead of below 20.

          1 triggered by 9<br>Array
          (
              [0] => Array
                  (
                      [0] => 1
                      [1] => 9
                  )
          
          )
          1 triggered by 27<br>Array
          (
              [0] => Array
                  (
                      [0] => 2
                      [1] => 27
                  )
          
          [1] => Array
              (
                  [0] => 1
                  [1] => 9
              )
          
          )
          2 triggered by 20<br>Array
          (
              [0] => Array
                  (
                      [0] => 2
                      [1] => 27
                  )
          
          [1] => Array
              (
                  [0] => 3
                  [1] => 20
              )
          
          [2] => Array
              (
                  [0] => 1
                  [1] => 9
              )
          
          )
          3 triggered by 19<br>Array
          (
              [0] => Array
                  (
                      [0] => 2
                      [1] => 27
                  )
          
          [1] => Array
              (
                  [0] => 3
                  [1] => 20
              )
          
          [2] => Array
              (
                  [0] => 4
                  [1] => 19
              )
          
          [3] => Array
              (
                  [0] => 1
                  [1] => 9
              )
          
          )
          2 triggered by 25<br>Array
          (
              [0] => Array
                  (
                      [0] => 2
                      [1] => 27
                  )
          
          [1] => Array
              (
                  [0] => 5
                  [1] => 25
              )
          
          [2] => Array
              (
                  [0] => 3
                  [1] => 20
              )
          
          [3] => Array
              (
                  [0] => 4
                  [1] => 19
              )
          
          [4] => Array
              (
                  [0] => 1
                  [1] => 9
              )
          
          )
          3 triggered by 23<br>Array
          (
              [0] => Array
                  (
                      [0] => 2
                      [1] => 27
                  )
          
          [1] => Array
              (
                  [0] => 5
                  [1] => 25
              )
          
          [2] => Array
              (
                  [0] => 6
                  [1] => 23
              )
          
          [3] => Array
              (
                  [0] => 3
                  [1] => 20
              )
          
          [4] => Array
              (
                  [0] => 4
                  [1] => 19
              )
          
          [5] => Array
              (
                  [0] => 1
                  [1] => 9
              )
          
          )
          4 triggered by 17<br>Array
          (
              [0] => Array
                  (
                      [0] => 2
                      [1] => 27
                  )
          
          [1] => Array
              (
                  [0] => 5
                  [1] => 25
              )
          
          [2] => Array
              (
                  [0] => 6
                  [1] => 23
              )
          
          [3] => Array
              (
                  [0] => 7
                  [1] => 17
              )
          
          [4] => Array
              (
                  [0] => 3
                  [1] => 20
              )
          
          [5] => Array
              (
                  [0] => 4
                  [1] => 19
              )
          
          [6] => Array
              (
                  [0] => 1
                  [1] => 9
              )
          
          )
          2 triggered by 26<br>Array
          (
              [0] => Array
                  (
                      [0] => 2
                      [1] => 27
                  )
          
          [1] => Array
              (
                  [0] => 8
                  [1] => 26
              )
          
          [2] => Array
              (
                  [0] => 5
                  [1] => 25
              )
          
          [3] => Array
              (
                  [0] => 6
                  [1] => 23
              )
          
          [4] => Array
              (
                  [0] => 7
                  [1] => 17
              )
          
          [5] => Array
              (
                  [0] => 3
                  [1] => 20
              )
          
          [6] => Array
              (
                  [0] => 4
                  [1] => 19
              )
          
          [7] => Array
              (
                  [0] => 1
                  [1] => 9
              )
          
          )

          Can anyone see where I've gone wrong and what I can do to fix this?

            I found my issue. It's that I wasn't shifting the lower values as something got inserted. It seems to be running properly with this addition but I'm incredibly embarrassed by my solution. If there's an elegant way to handle this, I'd love to hear it.

            		if($match_score > $sim1score){
            
            		array_splice($sim_array, 0, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $sim8score;
            		$sim8score = $sim7score;
            		$sim7score = $sim6score;
            		$sim6score = $sim5score;
            		$sim5score = $sim4score;
            		$sim4score = $sim3score;
            		$sim3score = $sim2score;
            		$sim2score = $sim1score;
            		$sim1score = $match_score;
            		$simstop = '1';
            		echo 1;
            	}elseif($match_score > $sim2score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 1, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $sim8score;
            		$sim8score = $sim7score;
            		$sim7score = $sim6score;
            		$sim6score = $sim5score;
            		$sim5score = $sim4score;
            		$sim4score = $sim3score;
            		$sim3score = $sim2score;
            		$sim2score = $match_score;
            		$simstop = '1';
            		echo 2;
            	}elseif($match_score > $sim3score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 2, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $sim8score;
            		$sim8score = $sim7score;
            		$sim7score = $sim6score;
            		$sim6score = $sim5score;
            		$sim5score = $sim4score;
            		$sim4score = $sim3score;
            		$sim3score = $match_score;
            		$simstop = '1';
            		echo 3;
            	}elseif($match_score > $sim4score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 3, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $sim8score;
            		$sim8score = $sim7score;
            		$sim7score = $sim6score;
            		$sim6score = $sim5score;
            		$sim5score = $sim4score;
            		$sim4score = $match_score;
            		$simstop = '1';
            		echo 4;
            	}elseif($match_score > $sim5score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 4, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $sim8score;
            		$sim8score = $sim7score;
            		$sim7score = $sim6score;
            		$sim6score = $sim5score;
            		$sim5score = $match_score;
            		$simstop = '1';
            		echo 5;
            	}elseif($match_score > $sim6score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 5, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $sim8score;
            		$sim8score = $sim7score;
            		$sim7score = $sim6score;
            		$sim6score = $match_score;
            		$simstop = '1';
            		echo 6;
            	}elseif($match_score > $sim7score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 6, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $sim8score;
            		$sim8score = $sim7score;
            		$sim7score = $match_score;
            		$simstop = '1';
            		echo 7;
            	}elseif($match_score > $sim8score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 7, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $sim8score;
            		$sim8score = $match_score;
            		$simstop = '1';
            		echo 8;
            	}elseif($match_score > $sim9score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 8, 0, array($match_array));
            		$sim10score = $sim9score;
            		$sim9score = $match_score;
            		$simstop = '1';
            		echo 9;
            	}elseif($match_score > $sim10score AND !ISSET($simstop)){
            
            		array_splice($sim_array, 9, 0, array($match_array));
            		$sim10score = $match_score;
            		$simstop = '1';
            		echo 10;
            	}
            	UNSET($simstop);
            	echo ' triggered by '.$match_score.'<br>';
            	print_r($sim_array);
            }

              Here's a roughed out example of what I was thinking as far as using usort() and such. (The first part is just setting up the initial array of 10 sub-arrays, so wouldn't necessarily be used in your actual code.)

              <?php
              // create initial array of score data
              $scores = array();
              for($i=1; $i<=10; $i++)
              {
              	$scores[] = array($i, rand(0,20));
              }
              usort($scores, function($a, $b)
              {
              	return($b[1] - $a[1]);
              });
              echo "Initial data:".PHP_EOL;
              var_export($scores);
              
              // a new score to be added
              $newScore = array(11, rand(1,19));
              echo "New score:".PHP_EOL;
              var_export($newScore);
              
              // put it into the score array, sort it, and cut it to 10 elements again
              $scores[] = $newScore;
              usort($scores, function($a, $b)
              {
              	return($b[1] - $a[1]);
              });
              $scores = array_slice($scores, 0, 10);
              echo "Final results:".PHP_EOL;
              var_export($scores);
              

              sample output:

              Initial data:
              array (
                0 =>
                array (
                  0 => 3,
                  1 => 19,
                ),
                1 =>
                array (
                  0 => 4,
                  1 => 11,
                ),
                2 =>
                array (
                  0 => 9,
                  1 => 8,
                ),
                3 =>
                array (
                  0 => 5,
                  1 => 8,
                ),
                4 =>
                array (
                  0 => 10,
                  1 => 7,
                ),
                5 =>
                array (
                  0 => 6,
                  1 => 7,
                ),
                6 =>
                array (
                  0 => 8,
                  1 => 6,
                ),
                7 =>
                array (
                  0 => 7,
                  1 => 6,
                ),
                8 =>
                array (
                  0 => 1,
                  1 => 4,
                ),
                9 =>
                array (
                  0 => 2,
                  1 => 3,
                ),
              )
              New score:
              array (
                0 => 11,
                1 => 7,
              )
              Final results:
              array (
                0 =>
                array (
                  0 => 3,
                  1 => 19,
                ),
                1 =>
                array (
                  0 => 4,
                  1 => 11,
                ),
                2 =>
                array (
                  0 => 5,
                  1 => 8,
                ),
                3 =>
                array (
                  0 => 9,
                  1 => 8,
                ),
                4 =>
                array (
                  0 => 11,
                  1 => 7,    <-- new score
                ),
                5 =>
                array (
                  0 => 6,
                  1 => 7,
                ),
                6 =>
                array (
                  0 => 10,
                  1 => 7,
                ),
                7 =>
                array (
                  0 => 8,
                  1 => 6,
                ),
                8 =>
                array (
                  0 => 7,
                  1 => 6,
                ),
                9 =>
                array (
                  0 => 1,
                  1 => 4,
                ),
              )
              
                Write a Reply...