-1

array_spliceここで説明されている戦略 を使用しようとしましたPHPの任意の位置に新しい項目を配列に挿入します

しかし、配列が空であるか、キーが存在しないため、機能しません。そこで、最初にキーが設定されているかどうかを確認してから作成してみました。しかし、それでもうまくいきません。

たとえば、最初の呼び出しで配列が空で、インデックス 3 に要素を挿入したい場合、 の前に位置 3 を作成するarray_spliceと、要素は位置 0 から挿入されarray_spliceます。配列が空の場合、挿入は失敗します

function array_insert($array,$input,$index){
    if(!isset($array[$index])) $array[$index] = 0;
    array_splice($array,$index,0,$input);

    return $array;
}

したがって、次の呼び出し

array_insert(array(),array(36,37),3);

これを生成します

array(1) { [3]=> int(0) } //var_dump before splice, after isset
array(3) { [0]=> int(0) [1]=> string(2) "36" [2]=> string(2) "37" } //var_dump  after splice

何が足りないの?!

@edit 期待される結果は次のとおりです。空の配列の位置 3 に array('a','b','c') を挿入すると、結果の配列により、キー 3、'b' で 'a' にアクセスできるようになります。 4などで。どちらが良いかわからない、ギャップを埋めるためのヌルまたは連想キー。

@編集2

insert(array(),array(1,2),3);

配列(2) { [3]=> int(1) [4]=> int(2) }

$a = array(); $a[2] = 3; insert($a,array(1,2),1);

配列(3) { 1 => int(1) [2]=> int(2) [3] => int(3) }

insert(array(1,2),array(4,5),1);

array(4) { [0]=> int(1) 1 => int(4) [2] => int(5) [3] => int(2) }

ところで、パフォーマンスの面で、より良い選択は何ですか?

4

3 に答える 3

2

これはあなたの要件を満たしていると思います。テスト ケースを含めましたので、ご自分で判断してください。

class ShiftingArray implements ArrayAccess
{
    private $values;

    public function __construct ($initial_values = array ())
    {
        $this->values = $initial_values;
    }

    public function get_values ()
    {
        return $this->values;
    }

    public function insert ($new_values, $offset)
    {
        if (!is_array ($new_values))
        {
            $new_values = array ($new_values);
        }

        foreach ($new_values as $value)
        {
            $this->insert_single ($offset, $value);
            $offset++;
        }
    }

    private function insert_single ($index, $value)
    {
        if (isset ($this->values[$index]))
        {
            $this->insert_single ($index + 1, $this->values[$index]);
        }
        $this->values[$index] = $value;
    }

    /**
    *   The following methods allow you to use an instance of ShiftingArray
    *   like a normal array, e.g.
    *
    *   $array = new ShiftingArray ();
    *   $array->insert (array (1,2,3), 4);
    *   echo $array[5]; //  prints 2
    */

    /*  boolean ArrayAccess::offsetExists (mixed $offset) */
    public function offsetExists ($offset)
    {
        return isset ($this->values [$offset]);
    }

    /*  mixed ArrayAccess::offsetGet (mixed $offset) */
    public function offsetGet ($offset)
    {
        return isset ($this->values [$offset]) ? $this->values[$offset] : null;
    }

    /*  ArrayAccess::offsetSet (mixed $offset, mixed $value) */
    public function offsetSet ($offset, $value)
    {
        $this->insert_single ($offset, $value);
    }

    /*  ArrayAccess::offsetUnset (mixed $offset) */
    public function offsetUnset ($offset)
    {
        unset ($this->values[$offset]);
    }
}

// begin test cases
$test_cases = array (
    array (
        'Name' => 'Start Empty, Zero Offset, Single Insert',
        'Initial' => array (),
        'Insert' => 6,
        'Offset' => 0,
        'Output' => array (0 => 6),
    ),
    array (
        'Name' => 'Start Empty, Zero Offset',
        'Initial' => array (),
        'Insert' => array (3, 2),
        'Offset' => 0,
        'Output' => array (0 => 3, 1 => 2),
    ),
    array (
        'Name' => 'Start Empty, Positive Offset, Single Insert',
        'Initial' => array (),
        'Insert' => 'hello',
        'Offset' => 11,
        'Output' => array (11 => 'hello'),
    ),
    array (
        'Name' => 'Start Empty, Positive Offset',
        'Initial' => array (),
        'Insert' => array (9, 'blah'),
        'Offset' => 3,
        'Output' => array (3 => 9, 4 => 'blah'),
    ),
    array (
        'Name' => 'No Shift',
        'Initial' => array (1 => 9),
        'Insert' => array (4, 'blah'),
        'Offset' => 3,
        'Output' => array (1 => 9, 3 => 4, 4 => 'blah'),
    ),
    array (
        'Name' => 'Single Shift',
        'Initial' => array (2 => 13),
        'Insert' => 6,
        'Offset' => 2,
        'Output' => array (2 => 6, 3 => 13),
    ),
    array (
        'Name' => 'Single Element, Double Shift',
        'Initial' => array (2 => 13),
        'Insert' => array (6, 7),
        'Offset' => 2,
        'Output' => array (2 => 6, 3 => 7, 4 => 13),
    ),
    array (
        'Name' => 'Multiple Element, Double Shift',
        'Initial' => array (5 => 13, 6 => 15),
        'Insert' => array (2, 3),
        'Offset' => 5,
        'Output' => array (5 => 2, 6 => 3, 7 => 13, 8 => 15),
    ),
    array (
        'Name' => 'Shift Only Some',
        'Initial' => array (2 => 1, 5 => 13, 6 => 15),
        'Insert' => array (2, 3),
        'Offset' => 5,
        'Output' => array (2 => 1, 5 => 2, 6 => 3, 7 => 13, 8 => 15),
    ),
    array (
        'Name' => 'Shift Fills Gaps',
        'Initial' => array (2 => 0, 3 => 11, 6 => 9, 7 => 'a'),
        'Insert' => array (12, 14),
        'Offset' => 4,
        'Output' => array (2 => 0, 3 => 11, 4 => 12, 5 => 14, 6 => 9, 7 => 'a'),
    ),
);

// run tests
$passes = $failures = 0;
foreach ($test_cases as $case)
{
    $array = new ShiftingArray ($case['Initial']);
    $array->insert ($case['Insert'], $case['Offset']);
    if ($array->get_values () != $case['Output'])
    {
        echo $case['Name'] . " FAILED\n";
        print_r ($array->get_values ());
        print_r ($case['Output']);
        echo "\n\n";
        $failures++;
    }
    else
    {
        $passes++;
    }
}
echo "\n\nTests Finished: $passes Passes, $failures Failures";
于 2015-06-10T00:34:06.983 に答える
1

しばらくして、私と友人はそれを機能させることができました。きっと多くの方のお役に立てると思います

function array_max_key($a){
  if(count($a)) return max(array_keys($a));
  return 0;
}

function array_insert($a,$b,$index){
  if(!is_array($b)) $b = array($b);

  $max = array_max_key($a);
  if($index > $max) $max = $index;
  $ab = array();
  $max++;

  for($i=0;$i<$max;$i++){
    if(isset($a[$i]) && $i<$index){
        $ab[$i] = $a[$i];
    }else if($i == $index){
        $_max = count($b);
        for($j=0;$j<$_max;$j++){
            $ab[$i+$j] = $b[$j];
        }
        if(isset($a[$i])) $ab[] = $a[$i];
    }else if(isset($a[$i])){
        if(isset($ab[$i])) $ab[] = $a[$i];
        else $ab[$i] = $a[$i];
    }
  }

  return $ab;
}

 array_insert(array(),array(1,2,3),4);
 $a = array(); $a[5] = 1; $a[6] = 2;
 array_insert($a,2,4);

したがって、配列の I 位置に要素を追加しようとすると、その位置が存在しない (または配列が空である) 場合でも要素が追加され、競合が見つかったときに他の要素がシフトされます。要素は配列であってもなくてもかまいません

于 2015-06-09T22:11:50.373 に答える