I have an array which contains list of pagrank values. Consider below array:
Array
(
[0] => stdClass Object
(
[pagerank] => 3
)
[1] => stdClass Object
(
[pagerank] => 1
)
[2] => stdClass Object
(
[pagerank] => R
)
[3] => stdClass Object
(
[pagerank] => 2
)
[4] => stdClass Object
(
[pagerank] => 7
)
)
I want to shift/move page rank with 'R' like:
[2] => stdClass Object
(
[pagerank] => R
)
to the end of array and it should be on last index of array?
Edit: The array key is unknown.
If the index is unknown:
foreach($array as $key => $val) {
if($val->pagerank == 'R') {
$item = $array[$key];
unset($array[$key]);
array_push($array, $item);
break;
}
}
If you don't want to modify the array while it is being iterated over just find the index then make the modifications.
$foundIndex = false;
foreach($array as $key => $val) {
if($val->pagerank == 'R') {
$foundIndex = $key;
break;
}
}
if($foundIndex !== false) {
$item = $array[$foundIndex];
unset($array[$foundIndex]);
array_push($array, $item);
}
$item = $array[2];
unset($array[2]);
array_push($array, $item);
Something like this?
$var = array(
'name' => 'thename',
'title' => 'thetitle',
'media' => 'themedia'
);
// Remove first element (the name)
$name = array_shift($var);
// Add it on to the end
$var['name'] = $name;
var_dump($var);
/*
array(3) {
["title"]=>
string(8) "thetitle"
["media"]=>
string(8) "themedia"
["name"]=>
string(7) "thename"
}
*/
Ref: http://forums.phpfreaks.com/topic/177878-move-array-index-to-end/
$item=null;
foreach ($array['pagerank'] as $key => $value)
{
if( $value=="R")
{
$item = $array[$key];
unset($array[$key]);
break;
}
}
if($item !=null)
array_push($array, $item);
Try this :
$arr = array(array("pagerank" => 3),
array("pagerank" => 1),
array("pagerank" => 'R'),
array("pagerank" => 4),
array("pagerank" => 7),
array("pagerank" => 5),
array("pagerank" => 2)
);
foreach($arr as $key=>$ar){
if($ar["pagerank"] == "R"){
$unset = $key;
break;
}
}
$val = $arr[$unset];
unset($arr[$unset]);
$arr[] = $val;
print_r($arr);
If what you're looking for is specifically the value of r, you can use array_search
array_search returns the key if an item exists in the array, otherwise returns false.
$needle = "R";
if($key = array_search($needle, $pageRankArray)) {
unset($pageRankArray[$key]); // Delete an item from the array
array_push($pageRankArray, $needle); // inserts element at the end of the array
}
If you want to place R as the last value and keeping your keys, you could do this:
$arr = array(
(object)array('pagerank' => 1),
(object)array('pagerank' => 'R'),
(object)array('pagerank' => 2),
);
// Store in temp var.
$tmp_arr = $arr;
// Sort temp array to put 'R' in top.
asort($tmp_arr);
// Reset to be able to find the first key in the sorted array.
reset($tmp_arr);
// Get key from first value in array.
$key = key($tmp_arr);
// Store value from first key.
$item = $tmp_arr[$key];
// Unset key from original array.
unset($arr[$key]);
// Insert as last value in original array using original key.
$arr[$key] = $item;
// Print result.
var_dump($arr);
This will give you:
array(3) {
[0]=>
object(stdClass)#1 (1) {
["pagerank"]=>
int(1)
}
[2]=>
object(stdClass)#3 (1) {
["pagerank"]=>
int(2)
}
[1]=>
object(stdClass)#2 (1) {
["pagerank"]=>
string(1) "R"
}
}
See: http://codepad.org/gPhrktuJ
foreach ($arr as $key => $value){
if ($value->pagerank == 'R'){
$arr[] = $value;
unset($arr[$key]);
break;
}
}
$arr = array_values($arr);
If you have more than one object with a 'R' value:
$current_array = $sorted_array = Array(
...
);
foreach($current_array as $current_key => $element){
if($element->pagerank == 'R'){
unset($sorted_array[$current_key]);
$sorted_array[] = $element;
}
}
unset($current_array);
Just use array_filter.
Taking $arr as input array:
$arr=Array
(
(Object) ['pagerank' => 3],
(Object) ['pagerank' => 1],
(Object) ['pagerank' => "R"],
(Object) ['pagerank' => 2],
(Object) ['pagerank' => 7],
);
$result=array_filter($arr,function($item){return $item->pagerank!="R";})+$arr;
var_dump($arr,$result);
The result will be:
array (size=5)
0 =>
object(stdClass)[1]
public 'pagerank' => int 3
1 =>
object(stdClass)[2]
public 'pagerank' => int 1
2 =>
object(stdClass)[3]
public 'pagerank' => string 'R' (length=1)
3 =>
object(stdClass)[4]
public 'pagerank' => int 2
4 =>
object(stdClass)[5]
public 'pagerank' => int 7
array (size=5)
0 =>
object(stdClass)[1]
public 'pagerank' => int 3
1 =>
object(stdClass)[2]
public 'pagerank' => int 1
3 =>
object(stdClass)[4]
public 'pagerank' => int 2
4 =>
object(stdClass)[5]
public 'pagerank' => int 7
2 =>
object(stdClass)[3]
public 'pagerank' => string 'R' (length=1)
Related
this one is a little Q&A-style...
i've been searching for this situation and couldn't find any solution, so i build my own.
it took me a few days to get a working code for my needs, but now i am wondering if there's a more efficient way:
$data = [
['a','aa','aaa'],
['a','aa','aab'],
['a','aa','aac'],
['a','ab'],
['a','ac','aca'],
['b','ba'],
['b','bb'],
['b','bc'],
];
function tree($values){
$on_end = sizeof($values) == 1 && sizeof($values[0]) == 0;
if ( $on_end ) return null;
$tree1 = [];
$tree2 = [];
foreach ($values as $a){
$parent = $a[0];
//remove the first column
array_shift($a);
$tree1[ $parent ][] = $a;
}
foreach ($tree1 as $parent => $b){
$tree2[ $parent ] = tree( $b );
}
return $tree2;
}
echo "<pre>".print_r(tree($data),true)."</pre>";
this is the result:
Array
(
[a] => Array
(
[aa] => Array
(
[aaa] =>
[aab] =>
[aac] =>
)
[ab] =>
[ac] => Array
(
[aca] =>
)
)
[b] => Array
(
[ba] =>
[bb] =>
[bc] =>
)
)
if anybody got a better one, please post it!
You have a shortest solution ... but it's using eval function erk
<?php
$data = [
['a','aa','aaa'],
['a','aa','aab'],
['a','aa','aac'],
['a','ab'],
['a','ac','aca'],
['b','ba'],
['b','bb'],
['b','bc'],
];
function arrayToTree_eval(array $source, $defaultValue = null) {
$tree = [];
foreach( $source as $values ) {
eval(sprintf('$tree%s = $defaultValue;', '["' . implode('"]["', $values) . '"]'));
}
return $tree;
}
var_dump( arrayToTree_eval($data) );
7 lines of code, and hop !
array (size=2)
'a' =>
array (size=3)
'aa' =>
array (size=3)
'aaa' => null
'aab' => null
'aac' => null
'ab' => null
'ac' =>
array (size=1)
'aca' => null
'b' =>
array (size=3)
'ba' => null
'bb' => null
'bc' => null
:)
In PHP we do have function array_flip for exchanging all keys with their associated values in an array, however I am looking for a the solution as follows with the help of php functions
INPUT
array(
"a" => 1,
"b" => 1,
"c" => 2
);
OUTPUT
array(
1 => array("a", "b"),
2 => "c"
);
I don't think there is a php function for it, so you'll have to write your own. If you really want a mixture of nested arrays and values the way to go would be:
function my_array_flip($arr)
{
$new_arr = array();
foreach ($arr as $k => $v)
{
if (array_key_exists($v, $new_arr))
{
if (is_array($new_arr[$v]))
{
$new_arr[] = $k;
}
else
{
$new_arr[$v] = array($new_arr[$v]);
$new_arr[$v][] = $k;
}
}
else
{
$new_arr[$v] = $k;
}
}
return $new_arr;
}
For your array this will return:
Array
(
[1] => Array
(
[0] => a
[1] => b
)
[2] => c
)
$source = array(
"a" => 1,
"b" => 1,
"c" => 2
);
foreach ($source as $key => $value)
{
$result[$value][] = $key;
}
Don't think exists a function for that but you can achieve it with some code:
$input = [
"a" => 1,
"b" => 1,
"c" => 2,
];
$grouped = [];
foreach ($input as $key => $group) {
$grouped[$group][] = $key;
}
Result:
var_dump($grouped);
array(2) {
[1] =>
array(2) {
[0] =>
string(1) "a"
[1] =>
string(1) "b"
}
[2] =>
array(1) {
[0] =>
string(1) "c"
}
}
Sets always array as values because I guess this will simplify things when you'll use the result in your code.
I must flattening of multidimensional table in PHP for the following functions to make them more readable. In addition, the effect of this script takes a little time. And here is the code that should work:
$data = array(
"one" => "one",
"two" => array(
"three" => "three",
"four" => "four",
),
"five" => "five",
"six" => array(
"seven" => "seven",
"eight" => array(
"nine" => "nine",
"ten" => "ten"
)
)
);
$flat=array();
do{
$newFlat=array();
if(empty($data)) break;
if(empty($flat)) $flat = $data;
$findArray = FALSE;
foreach($flat as $key => $value){
if(is_array($value)){
if(is_string($key)) $newFlat[] = 'Start'.$key;
foreach($value as $keySec => $valueSec){
if(is_array($valueSec)){
if(is_string($keySec)) $newFlat[] = 'Start'.$keySec;
$newFlat[] = $valueSec;
if(is_string($keySec)) $newFlat[] = 'End'.$keySec;
$findArray = TRUE;
}else{
$newFlat[$keySec] = $value;
}
}
if(is_string($key)) $newFlat[] = 'End'.$key;
}else{
$newFlat[$key] = $value;
}
}
$flat = $newFlat;
}while($findArray);
print_r($flat);
Result is a $flat. May know how to convert this script to exploit less time and less memory? I want the result looks like this:
/*
Result $flat looking like it:
$flat = [
'one' => 'one',
1 => 'Starttwo',
'three' => 'three',
'four' => 'four',
4 => 'Endtwo',
'five' => 'five,
6 => 'StartSix',
'seven' => 'seven',
8 => 'Starteight',
'nine' => 'nine',
'ten' => 'ten',
11 => 'Endeight',
12 => 'EndSix'
];
*/
Ps. Sorry for my reprehensible English. I think that, in spite of this, you will understand me.
Try this:
function flatten_array($data) {
$newArray = array();
foreach ($data as $key => $value) {
if (is_array($value)) {
$newArray[] = 'Start' . $key;
$newArray = array_merge($newArray,flatten_array($value));
$newArray[] = 'End' . $key;
} else {
$newArray[$key] = $value;
}
}
return $newArray;
}
$flat = flatten_array($data);
print_r($flat);
output:
Array
(
[one] => one
[0] => Starttwo
[three] => three
[four] => four
[1] => Endtwo
[five] => five
[2] => Startsix
[seven] => seven
[3] => Starteight
[nine] => nine
[ten] => ten
[4] => Endeight
[5] => Endsix
)
Try:
class array_class
{
public $data = array();
public $new_array = array();
public $value = 1;
public $number = "";
public function __construct($data)
{
$this->data = $data;
$this->flatten_array($this->data);
}
private function flatten_array($array)
{
foreach($array as $key => $value)
{
if(is_array($value))
{
$this->number = $key;
$this->new_array[$this->value++] = "Start" . $key;
$this->flatten_array($value);
}
else
{
$this->new_array[$key] = $value;
$this->value++;
}
}
$this->new_array[$this->value] = "End" . $this->number;
}
}
Output:
Array
(
[one] => one
[2] => Starttwo
[three] => three
[four] => four
[5] => Endtwo
[five] => five
[6] => Startsix
[seven] => seven
[8] => Starteight
[nine] => nine
[ten] => ten
[11] => Endeight
)
Hi it is any way to connect to records where value is the same?
like
[12]=> Array (
[ID] => 127078
[row1] =>
[post] => N16 7UJ
)
[13]=> Array (
[ID] => 127078
[row1] => something
[post] =>
)
and make like that
[12]=> Array (
[ID] => 127078
[row1] => something
[post] => N16 7UJ
)
Here take this function
<?php
$array = array(
12 => array (
"ID" => '127078',
"row1" => '',
"post" => 'N16 7UJ',
),
13 => array (
"ID" => '127078',
"row1" => 'something',
"post" => '',
)
);
function mergedup($array,$matcher){
if(!function_exists('remove_element')){
function remove_element($arr,$element){
$ret_arr = array();
foreach($arr as $val){
if($val !== $element){
array_push($ret_arr,$val);
}
}
return $ret_arr;
}
}
$array = remove_element($array,array());
$return_array = array();
while(isset($array[0])){
$temp = $array[0];
$array = remove_element($array,$temp);
$array_temp = array();
foreach($array as $vals){
if($temp[$matcher]==$vals[$matcher]){
array_push($array_temp,$vals);
foreach($temp as $key => $val){
if(empty($temp[$key])){
$temp[$key] = $vals[$key];
}
}
}
}
foreach($array_temp as $vals){
$array = remove_element($array,$vals);
}
array_push($return_array,$temp);
}
return $return_array;
}
var_dump(mergedup($array,"ID"));
?>
Tested and working
You have so many option such as array_replace
array_merge
foreach
while
Iterator
But i prefer array_replace because you can easily select which array is replacing which
Values
$array[12] = array("ID"=>127078,"row1"=>"","post"=>"N16 7UJ");
$array[13] = array("ID"=>127078,"row1"=>"something","post"=>"");
var_dump($array[12]);
Example array_replace ( http://www.php.net/manual/en/function.array-replace.php )
$array[13] = array_filter($array[13]); //Filter Replacement
$array[12]= array_replace($array[12],$array[13]);
Example array_merge ( http://php.net/manual/en/function.array-merge.php )
//$array[12] = array_filter($array[12]); //Optinal
$array[13] = array_filter($array[13]); //Filter Spaces
$array[12]= array_merge($array[12],$array[13]);
var_dump($array[12]);
Output
array
'ID' => int 127078
'row1' => string 'something' (length=9)
'post' => string 'N16 7UJ' (length=7)
I've an array of folders/paths:
$arr = Array
(
0 => Array
(
'name' => 'aaa'
),
1 => Array
(
'name' => 'aaa\bbb'
),
2 => Array
(
'name' => 'aaa\bbb\ccc'
),
3 => Array
(
'name' => 'ddd'
)
);
I'd like to transform it to multidimensional (tree-like) array (keeping the structure: index/key & value/name):
aaa
bbb
ccc
ddd
Any suggests?
Try:
$arr = array(
array('name' => 'aaa'),
array('name' => 'aaa\bbb'),
array('name' => 'aaa\bbb\ccc'),
array('name' => 'ddd'),
array('name' => 'ddd\zzz'),
array('name' => 'zzz'),
array('name' => 'ddd\zzz\fff'),
);
$new = array();
$helper = array();
foreach ($arr as $i => $entry) {
$parent =& $new;
/**
* One could use:
* explode(DIRECTORY_SEPARATOR, $entry['name'])
*
* instead of '\\' if you're dealing with file-structures
*/
foreach ($path = explode('\\', $entry['name']) as $ii => $element) {
$subPath = implode('.', array_slice($path, 0, $ii + 1));
if (isset($helper[$subPath])) {
$parent =& $helper[$subPath];
continue;
}
$parent[$i] = array('name' => $element);
$helper[$subPath] =& $parent[$i];
}
}
print_r($new);
Output:
Array
(
[0] => Array
(
[name] => aaa
[1] => Array
(
[name] => bbb
[2] => Array
(
[name] => ccc
)
)
)
[3] => Array
(
[name] => ddd
[4] => Array
(
[name] => zzz
[6] => Array
(
[name] => fff
)
)
)
[5] => Array
(
[name] => zzz
)
)
$newarr=array();
foreach ($arr as $element) {
$currentroot=$newarr;
$pieces=explode('\\', $element);
for ($x=0; $x<=count($pieces); x++) {
$currentroot[$pieces[$x]]=array();
$currentroot=$currentroot[$pieces[$x]];
}
}
Untested but should get you started. You need to add a condition to check if it is the last piece, and make it a string value instead of an array.
Well, had to do it in two functions, but here goes:
// Directory Array to Hierarchy
function _DAtoH($path, $result = null)
{
if (empty($path)) return array();
if (is_null($result)) $result = array();
$path = explode(DIRECTORY_SEPARATOR, $path);
$curr = array_shift($path);
if (!isset($result[$curr]))
$result[$curr] = array();
$result[$curr] = _DAtoH(implode(DIRECTORY_SEPARATOR, $path), $result[$curr]);
return $result;
}
function DAtoH($arr)
{
$result = array();
foreach ($arr as $a)
$result = _DAtoH($a,$result);
return $result;
}
Passing the bottom function (the _DAtoH is just a recursive helper) the array you specified in your original question (var_dump(DAtoH($arr));), you should receive:
array(2) {
["aaa"]=>
array(2) {
["bbb"]=>
array(1) {
["ccc"]=>
array(0) {
}
}
["fff"]=>
array(0) {
}
}
["ddd"]=>
array(1) {
["eee"]=>
array(0) {
}
}
}
(Note: I added some folder paths just to test it out, thus the fff, eee, etc.)
For the new requirements:
$arr = array(
array('name' => 'aaa'),
array('name' => 'aaa\bbb'),
array('name' => 'aaa\bbb\ccc'),
array('name' => 'ddd'),
);
function traverse(array $array) {
$mark=array_shift($array);
return array($mark => $array ? traverse($array) : array() );
}
$out = array();
foreach($arr as $path)
{
($add=traverse(explode('\\',$path['name'])))
&& $out[key($add)]=current($add)
;
}
Output:
array(2) {
["aaa"]=>
array(1) {
["bbb"]=>
array(1) {
["ccc"]=>
array(0) {
}
}
}
["ddd"]=>
array(0) {
}
}
Old Question:
The old question had these reqs:
$arr = array(
0 => 'aaa',
1 => 'aaa\bbb',
2 => 'aaa\bbb\ccc',
);
function traverse(array $array) {
$mark=array_shift($array);
return $array ? array($mark => traverse($array)) : $mark;
}
$out = array();
foreach($arr as $path)
{
is_array($add=traverse(explode('\\',$path)))
&& $out[key($add)]=current($add)
;
}
Tested, giving this output:
array(1) {
["aaa"]=>
array(1) {
["bbb"]=>
string(3) "ccc"
}
}