jeudi 1 mai 2014

Tri - changement de Position des clés dans tableaux associatifs - Stack Overflow


I'm creating a form generator that takes some configuration arrays and build the html. Ex: I have the following associative array to describe how the fields should be displayed:


$fieldSpec = array(
'nome' => array(
'label' => 'Nome',
),
'descricao' => array(
'label' => 'Descrição',
),
'preco' => array(
'label' => 'Preço',
),
);

problem: I want to reposition the keys easily without having to be cutting & pasting all the time. So i thought to ask somebody if they know a function or class to manage this; it would have to be something like this:


ChangeKeyPosition(&$fieldSpec,'preco','up',2);

// that would produce:
$fieldSpec = array(
'preco' => array( # <- notice this element came 2 levels up
'label' => 'Preço',
),
'nome' => array(
'label' => 'Nome',
),
'descricao' => array(
'label' => 'Descrição',
),

);

other possible features I would like to have:


ChangeKeyPosition(&$fieldSpec,'descricao','down',1);
// send element "preco" to the top
ChangeKeyPosition(&$fieldSpec,'preco','top');
// send element "nome" to the end of the array
ChangeKeyPosition(&$fieldSpec,'nome','bottom');
// place "nome" before "preco"
ChangeKeyPosition(&$fieldSpec,'nome','before','preco');
// place "nome" after "descricao"
ChangeKeyPosition(&$fieldSpec,'nome','after','descricao');
// place "preco" between "nome" and "descricao"
ChangeKeyPosition(&$fieldSpec,'preco','between',array('nome','descricao'));

I would even prefer to work with an object wrapping the array reference like this:


$man = new KeyPositionManager(&$fieldSpec);
$man->up('preco',2);
$man->after('nome','descricao');
etc...

Update: So I ended up creating a set of functions myself to do just what I was asking for. It may or may not be useful for somebody else:


function array_key_move(&$oarr, $key, $move)
{
$keys = array_keys($oarr);
$opos = array_search($key,$keys);
if($opos===false) return;
$npos = $opos + $move + ($move > 0 ? +0.1 : -0.1);
$keys["$npos"] = $key;
unset($keys[$opos]);
ksort($keys);
foreach($keys as $k)
{
$narr[$k] = $oarr[$k];
}
$oarr = $narr;
}

function array_key_set_at(&$oarr, $tkey, $nkey, $nval, $before = true)
{
$tpos = array_search($tkey,array_keys($oarr));
if($tpos===false) return;
$narr = array();
$i = 0;
foreach($oarr as $k => $v)
{
if($tpos==$i)
{
$before AND $narr[$nkey] = $nval;
$narr[$k] = $v;
$before OR $narr[$nkey] = $nval;
} else $narr[$k] = $v;
$i++;
}
$oarr = $narr;
}

function array_key_move_before(&$oarr, $key_element, $key_target)
{
$copy_element = $oarr[$key_element];
unset($oarr[$key_element]);
array_key_set_at($oarr, $key_target, $key_element, $copy_element, TRUE);
}

function array_key_move_after(&$oarr, $key_element, $key_target)
{
$copy_element = $oarr[$key_element];
unset($oarr[$key_element]);
array_key_set_at($oarr, $key_target, $key_element, $copy_element, FALSE);
}

function array_key_move_start(&$oarr, $key)
{
if(!isset($oarr[$key])) return;
$narr[$key] = $oarr[$key];
foreach($oarr as $k => $v)
{
$k!=$key AND $narr[$k]=$v;
}
$oarr = $narr;
}

function array_key_move_end(&$oarr, $key)
{
if(!isset($oarr[$key])) return;
foreach($oarr as $k => $v)
{
$k!=$key AND $narr[$k]=$v;
}
$narr[$key] = $oarr[$key];
$oarr = $narr;
}

function array_key_set_start(&$oarr,$key,$val)
{
$oarr[$key] = $val;
array_key_move_start($oarr,$key);
}


function array_key_set_end(&$oarr,$key,$val)
{
$oarr[$key]=$val; # :-)
}

function array_key_switch2(&$oarr,$ka,$kb)
{
$keys = array_keys($oarr);
if(($kapos = array_search($ka, $keys))===false) return;
if(($kbpos = array_search($kb, $keys))===false) return;
$i = 0;
foreach($oarr as $k => $v)
{
if($i==$kapos)
$narr[$kb] = $oarr[$ka];
elseif($i==$kbpos)
$narr[$ka] = $oarr[$kb];
else
$narr[$k] = $v;
$i++;
}
$oarr = $narr;
}

Examples:


array_key_move($arr,'f',-3);


Array
(
[a] => 1
[b] => 2
[f] => 6 # <- "f"
[c] => 3 #
[d] => 4 #
[e] => 5
)

array_key_move($arr,'a',+1);


Array
(
[b] => 2 #
[a] => 1 # <- "a"
[f] => 6
[c] => 3
[d] => 4
[e] => 5
)

array_key_move_after($arr,'b','e');


Array
(
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[e] => 5
[b] => 2 # <- "b" after "e"
)

array_key_move_start($arr,'b');


Array
(
[b] => 2 # <- "b" at start
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[e] => 5
)

array_key_set_start($arr,'r',7);


Array
(
[r] => 7 # <- prepended
[b] => 2
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[e] => 5
)

*obs: the above is not an alias to array_unshift ex: array_unshift($arr,array('r'=>7)); would produce:*


Array
(
[0] => Array
(
[r] => 7
)

[b] => 2
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[e] => 5
)

and finally


array_key_switch2($arr,'r','e');


Array
(
[e] => 7 # <-
[b] => 2
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[r] => 5 # <-
)


I'm creating a form generator that takes some configuration arrays and build the html. Ex: I have the following associative array to describe how the fields should be displayed:


$fieldSpec = array(
'nome' => array(
'label' => 'Nome',
),
'descricao' => array(
'label' => 'Descrição',
),
'preco' => array(
'label' => 'Preço',
),
);

problem: I want to reposition the keys easily without having to be cutting & pasting all the time. So i thought to ask somebody if they know a function or class to manage this; it would have to be something like this:


ChangeKeyPosition(&$fieldSpec,'preco','up',2);

// that would produce:
$fieldSpec = array(
'preco' => array( # <- notice this element came 2 levels up
'label' => 'Preço',
),
'nome' => array(
'label' => 'Nome',
),
'descricao' => array(
'label' => 'Descrição',
),

);

other possible features I would like to have:


ChangeKeyPosition(&$fieldSpec,'descricao','down',1);
// send element "preco" to the top
ChangeKeyPosition(&$fieldSpec,'preco','top');
// send element "nome" to the end of the array
ChangeKeyPosition(&$fieldSpec,'nome','bottom');
// place "nome" before "preco"
ChangeKeyPosition(&$fieldSpec,'nome','before','preco');
// place "nome" after "descricao"
ChangeKeyPosition(&$fieldSpec,'nome','after','descricao');
// place "preco" between "nome" and "descricao"
ChangeKeyPosition(&$fieldSpec,'preco','between',array('nome','descricao'));

I would even prefer to work with an object wrapping the array reference like this:


$man = new KeyPositionManager(&$fieldSpec);
$man->up('preco',2);
$man->after('nome','descricao');
etc...

Update: So I ended up creating a set of functions myself to do just what I was asking for. It may or may not be useful for somebody else:


function array_key_move(&$oarr, $key, $move)
{
$keys = array_keys($oarr);
$opos = array_search($key,$keys);
if($opos===false) return;
$npos = $opos + $move + ($move > 0 ? +0.1 : -0.1);
$keys["$npos"] = $key;
unset($keys[$opos]);
ksort($keys);
foreach($keys as $k)
{
$narr[$k] = $oarr[$k];
}
$oarr = $narr;
}

function array_key_set_at(&$oarr, $tkey, $nkey, $nval, $before = true)
{
$tpos = array_search($tkey,array_keys($oarr));
if($tpos===false) return;
$narr = array();
$i = 0;
foreach($oarr as $k => $v)
{
if($tpos==$i)
{
$before AND $narr[$nkey] = $nval;
$narr[$k] = $v;
$before OR $narr[$nkey] = $nval;
} else $narr[$k] = $v;
$i++;
}
$oarr = $narr;
}

function array_key_move_before(&$oarr, $key_element, $key_target)
{
$copy_element = $oarr[$key_element];
unset($oarr[$key_element]);
array_key_set_at($oarr, $key_target, $key_element, $copy_element, TRUE);
}

function array_key_move_after(&$oarr, $key_element, $key_target)
{
$copy_element = $oarr[$key_element];
unset($oarr[$key_element]);
array_key_set_at($oarr, $key_target, $key_element, $copy_element, FALSE);
}

function array_key_move_start(&$oarr, $key)
{
if(!isset($oarr[$key])) return;
$narr[$key] = $oarr[$key];
foreach($oarr as $k => $v)
{
$k!=$key AND $narr[$k]=$v;
}
$oarr = $narr;
}

function array_key_move_end(&$oarr, $key)
{
if(!isset($oarr[$key])) return;
foreach($oarr as $k => $v)
{
$k!=$key AND $narr[$k]=$v;
}
$narr[$key] = $oarr[$key];
$oarr = $narr;
}

function array_key_set_start(&$oarr,$key,$val)
{
$oarr[$key] = $val;
array_key_move_start($oarr,$key);
}


function array_key_set_end(&$oarr,$key,$val)
{
$oarr[$key]=$val; # :-)
}

function array_key_switch2(&$oarr,$ka,$kb)
{
$keys = array_keys($oarr);
if(($kapos = array_search($ka, $keys))===false) return;
if(($kbpos = array_search($kb, $keys))===false) return;
$i = 0;
foreach($oarr as $k => $v)
{
if($i==$kapos)
$narr[$kb] = $oarr[$ka];
elseif($i==$kbpos)
$narr[$ka] = $oarr[$kb];
else
$narr[$k] = $v;
$i++;
}
$oarr = $narr;
}

Examples:


array_key_move($arr,'f',-3);


Array
(
[a] => 1
[b] => 2
[f] => 6 # <- "f"
[c] => 3 #
[d] => 4 #
[e] => 5
)

array_key_move($arr,'a',+1);


Array
(
[b] => 2 #
[a] => 1 # <- "a"
[f] => 6
[c] => 3
[d] => 4
[e] => 5
)

array_key_move_after($arr,'b','e');


Array
(
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[e] => 5
[b] => 2 # <- "b" after "e"
)

array_key_move_start($arr,'b');


Array
(
[b] => 2 # <- "b" at start
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[e] => 5
)

array_key_set_start($arr,'r',7);


Array
(
[r] => 7 # <- prepended
[b] => 2
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[e] => 5
)

*obs: the above is not an alias to array_unshift ex: array_unshift($arr,array('r'=>7)); would produce:*


Array
(
[0] => Array
(
[r] => 7
)

[b] => 2
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[e] => 5
)

and finally


array_key_switch2($arr,'r','e');


Array
(
[e] => 7 # <-
[b] => 2
[a] => 1
[f] => 6
[c] => 3
[d] => 4
[r] => 5 # <-
)

0 commentaires:

Enregistrer un commentaire