2013-04-09 17 views
5

型キャスト時に重複するキーを防ぐ最良の方法は何ですか?配列内の重複キー

例:

//Credits @bwoebi 
$obj = (object)array(1,2,3); 
$obj->{1} = "Duplicate key 1"; 
$obj->{2} = "Duplicate key 2"; 
$obj->{3} = "Duplicate key 3"; 
$array = (array)$obj ; 
print_r($array); 

出力

Array 
(
    [0] => 1 
    [1] => 2 
    [2] => 3 
    [1] => Duplicate key 1 
    [2] => Duplicate key 2 
    [3] => Duplicate key 3 
) 

は今、私はいくつかのスマートな人々は言うだろう知っているその1 keystringや他のint使用ですのでvar_dump

var_dump($array); 

出力

array (size=6) 
    0 => int 1 
    1 => int 2 
    2 => int 3 
    '1' => string 'Duplicate key 1' (length=15) 
    '2' => string 'Duplicate key 2' (length=15) 
    '3' => string 'Duplicate key 3' (length=15) 

しかし、主な問題があるがループすることなく、この問題の任意の回避策も、キー

echo $array['1'] ,PHP_EOL;  //Expected Duplicate key 1 
echo $array[1] ,PHP_EOL; 

出力

2 
2 

を取得する方法はありません?明らかに、@PeeHaa埽が再びビールにならない限り、私はこのミスを決してしませんでしたが、どんな答えでも教育を受けたPHPの開発者に役立つはずです。

。 - これはイースリーあなたは配列のキーをリセットするためにarray_values機能を使用することができますarray_valuessortまたはキーの位置を変更する任意のPHP関数

sort($array); 
print_r($array); 

出力

Array 
(
    [0] => Duplicate key 1 
    [1] => Duplicate key 2 
    [2] => Duplicate key 3 
    [3] => 1 
    [4] => 2 
    [5] => 3 
) 
+1

この質問は、キーの「重複」の防止や正しい値へのアクセスについてですか? – PeeHaa

+0

@PeeHaa埽私は両方とも.... – Baba

答えて

1

で解決することができます。

はこれを試してみてください:

Array 
(
    [0] => 1 
    [1] => 2 
    [2] => 3 
    [3] => Duplicate key 1 
    [4] => Duplicate key 2 
    [5] => Duplicate key 3 
) 

それとも、あなたもこのようにキャストする前にarray_valuesを使用することができます:

$array = array_values((array)$obj); 

は、この情報がお役に立てば幸い!

$obj = (object)array(1,2,3); 
$obj->{1} = "Duplicate key 1"; 
$obj->{2} = "Duplicate key 2"; 
$obj->{3} = "Duplicate key 3"; 
$array = (array)$obj ; 

$array = array_values($array); 
print_r($array); 

はこれを生成します

+0

'array_values'はい、私は'任意の答えは教育されたPHP開発者を助けるべきだ 'と言っています – Baba

+0

PHPの開発者を教育するのに役立つ "答え"はどういう意味ですか?答えはより良く説明されるべきですか? – Matija

+0

Yes 'better better' .....広い開発者のために.....ありがとう – Baba

1

おそらく最適な解決策ではないかもしれませんが、配列をオブジェクトにキャストするカスタム関数を使用すると、問題の一部が解決されます。

// function that convers an array to an object, and prefixes the numeric values with a string 
function toObj(Array $arr, $prefix = '_', $convertAll = false) { 
    foreach ($arr as $key => $value) { 
     if (is_numeric($key) || $convertAll) { 
      unset($arr[$key]); 
      $arr[$prefix . $key] = $value; 
     } 
    } 
    return (object)$arr; 
} 

$obj = toObj(array(1, 2, 3)); 
$obj->{'_0'} = "Duplicate key 0"; // either this way 
$obj->_1 = "Duplicate key 1"; // or this way 
$obj->{'_2'} = "Duplicate key 2"; 
$array = (array)$obj; 
print_r($array); 

結果は:

Array 
(
    [_0] => Duplicate key 0 
    [_1] => Duplicate key 1 
    [_2] => Duplicate key 2 
) 

このarray_values溶液と同様であるが、それは依然として、少なくともある程度まで、キーを維持するという利点を有します。

1

解決方法(これは醜いハックではない唯一のことです)は、匿名オブジェクトの使用をやめ、この目的のためにクラスを定義することです。

があるため __set()の使用およびダイナミックパブリックプロパティとして定義するすべての
class SimpleArrayObject 
{ 
    public function __construct($array = null) 
    { 
     foreach ((array) $array as $key => $value) { 
      $this->{$key} = $value; // implicitly calls __set() 
     } 
    } 

    public function __set($key, $value) 
    { 
     $this->{(string) $key} = $value; 
    } 
} 

、これはまだキャスト、json_encode()foreachで素晴らしいプレーし、他のすべてのものは、あなたから期待する:それは複雑にする必要はありません。 a stdClass。ただしこれはプロパティ名の文字列型を強制します。つまり、オーバーラップする緩い型はもはや不可能です。

また、あなたは何が起こっている "キャスト" の構文は非常に明らかにすることを可能にするためのヘルパー関数を定義することができます。

function object($value) 
{ 
    if (is_object($value)) { 
     return $value; 
    } 

    if (!is_array($value)) { // mimic the behaviour of a regular cast 
     $value = array('scalar' => $value); 
    } 

    return new SimpleArrayObject($value); 
} 

何が起こるかを参照してください:

$obj = object(array(1,2,3)); 
$obj->{1} = "Duplicate key 1"; 
$obj->{2} = "Duplicate key 2"; 
$obj->{3} = "Duplicate key 3"; 
$array = (array)$obj ; 
print_r($array); 

Output

Array 
(
    [0] => 1 
    [1] => Duplicate key 1 
    [2] => Duplicate key 2 
    [3] => Duplicate key 3 
) 
+0

+ Very Nice ...... – Baba