Flattening of multidimensional table in PHP - php

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
)

Related

Only permit one instance of a row with a particular column value in a multidimensional array

In my input array, I have multiple rows with a userTag of All, but I only want a maximum of one. Other rows my have duplicated userTag values (such as Seeker), but extra All rows must be removed.
$input = [
0 => ['userTag' => 'All', 'fbId' => 10210118553469338, 'price' => 70],
1 => ['userTag' => 'All', 'fbId' => 10210118553469338, 'price' => 14],
2 => ['userTag' => 'All', 'fbId' => 10210118553469338, 'price' => null],
3 => ['userTag' => 'Seeker', 'fbId' => 10207897577195936, 'price' => 65],
6 => ['userTag' => 'Seeker', 'fbId' => 709288842611719, 'price' => 75],
17 => ['userTag' => 'Trader', 'fbId' => 2145752308783752, 'price' => null]
];
My current code:
$dat = array();
$dat2 = array();
foreach ($input as $key => $value)
{
$i = 0;
$j = 0;
if (count($dat) == 0) {
$dat = $input[$key];
$i++;
} else {
if ($input[$key]['userTag'] == "All") {
if ($this->check($input[$key]['fbId'], $dat) == false) {
$dat[$i] = $input[$key];
$i++;
}
} else {
$dat2[$j] = $input[$key];
$j++;
}
}
}
$data = array_merge($dat, $dat2);
return $data;
The check() function:
public function check($val, $array) {
foreach ($array as $vl) {
if ($val == $array[$vl]['fbId']) {
return true;
break;
}
}
return false;
}
You can try something simple like this:
$data = [];
foreach($input as $key => $value)
{
$counter = 0;
if($value['userTag'] =="All"){
if($counter == 0 ) {//test if is the first userTag == All
$counter = 1;//increment the counter so the if doesn't trigger and the value isn't appended
$data[] = $value;//add it to the array
}
} else {
$data[] = $value;//keep the rest of the values
}
}
return $data;
You can use the below code, This will remove all duplicate values from your array.
$arr = array_map("unserialize", array_unique(array_map("serialize", $arr)));
UPDATED ANSWER
The updated answer below is the accurate solution asked in the question which helps with All rows data too.
$temp = array();
foreach($arr as $key => $val) {
if ($val['userTag'] == "All" && empty($temp)) {
$temp[$key] = $arr[$key];
unset($arr[$key]);
}
else if ($val['userTag'] == "All") {
unset($arr[$key]);
}
}
$arr = array_merge($arr, $temp);
Check this code. Perfectly working.
$n_array = array();$i=0;
foreach($array as $row){
if($row['userTag']=="All"){
if($i==0){
$n_array[]=$row;
$i=1;
}
}
else $n_array[]=$row;
}
echo "<pre>";print_r($n_array);
Result
Array
(
[0] => Array
(
[userTag] => All
[fbId] => 10210118553469338
[fName] => Danish
[lName] => Aftab
[imageUrl] => https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/22491765_10210410024475931_8589925114603818114_n.jpg?oh=7fa6266e7948ef2d218076857972f7e0
[subsType] => gold
[user_visible] => 0
[distance] => 0.01
[advising] => 0
[avgRate] => 4
[totalReview] => 2
[us_seeker_type] => new
[price] => 70
)
[1] => Array
(
[userTag] => Seeker
[fbId] => 10207897577195936
[fName] => Saq
[lName] => Khan
[imageUrl] => https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/21151741_10207631130774942_8962953748374982841_n.jpg?oh=f5e5b9dff52b1ba90ca47ade3d703b01
[subsType] => gold
[user_visible] => 0
[background] =>
[topic] =>
[distance] => 0.01
[advising] => 0
[avgRate] => 0
[totalReview] => 0
[us_seeker_type] => new
[price] => 65
)
[2] => Array
(
[userTag] => Seeker
[fbId] => 709288842611719
[fName] => Muhammad
[lName] => Hasan
[imageUrl] => https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/20264704_681395725401031_2098768310549259034_n.jpg?oh=36db5b6ed60214088750794d4e3aa3e6
[subsType] => gold
[user_visible] => 0
[distance] => 0.02
[advising] => 0
[avgRate] => 0
[totalReview] => 0
[us_seeker_type] => new
[price] => 75
)
[3] => Array
(
[userTag] => Trader
[fbId] => 2145752308783752
[fName] => Jawaid
[lName] => Ahmed
[imageUrl] => https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/20992899_2068273703198280_4249128502952085310_n.jpg?oh=6df0be6ced405dd66ee50de238156183
[subsType] => basic
[user_visible] => 0
[advising] => 0
[distance] => 0
[avgRate] => 0
[totalReview] => 0
[utr_trader_type] => new
[price] =>
)
)
To keep only the first occurrence of the All row, build an array where All is used as a first level key in the result array. If the row isn't an All row, just keep using its original numeric key. Using the ??= "null coalescing assignment operator", you ensure that only the first All value is stored and all subsequently encountered All rows are ignored.
Code: (Demo)
$result = [];
foreach ($array as $key => $row) {
$result[$row['userTag'] === 'All' ? 'All' : $key] ??= $row;
}
var_export($result);
If you don't want to have the All key for later processing reasons, you can replace it by un-setting then re-pushing it into the array (after finishing the loop).
$result[] = $result['All']; // or unshift($result, $result['All']) to the start of the array
unset($result['All']);

how to create unique array from array

Array
[0] => Array
(
[a1] => 12
[v1] => 3100.00
[v2] => 186.00
[v3] => 186.00
)
[1] => Array
(
[a1] => 12
[v1] => 1200.00
[v2] => 72.00
[v3] => 72.00
)
i want to create new array from this array
which is look like this as given below it should give me '12' common and add other values
Array
[0] => Array
(
[a1] => 12
[v1] => 4300.00
[v2] => 258.00
[v3] => 258.00
)
Try This code ,
foreach($value as $i=>$v) {
$temp[0]['a1'] = $v['a1'];
$temp[0]['v1'] += $v['v1'];
$temp[0]['v2'] += $v['v2'];
$temp[0]['v3'] += $v['v3'];
}
Please find below code:
<?php
$merged = array();
$res = array('a1'=>12,'v1'=>3100.00,'v2'=>186.00,'v3'=>186.00);
$res1 = array('a1'=>12,'v1'=>1200.00,'v2'=>72.00,'v3'=>72.00);
foreach ([$res, $res1] as $a) { // iterate both arrays
foreach ($a as $key => $value) { // iterate all keys+values
$merged[$key] = $value + (isset($merged[$key]) ? $merged[$key] : 0); // merge and add
}
}
print "<pre>";
print_r($merged);
die;
?>
It's a bit unclear the real your needs, so this solution only one of a few possible solutions.
This script a1 element is using as key, so it will work with more than one a1 value.
Example:
<?php
$a = [
[
'a1' => 12,
'v1' => 3100.00,
'v2' => 186.00,
'v3' => 186.00,
],
[
'a1' => 12,
'v1' => 1200.00,
'v2' => 72.00,
'v3' => 72.00,
],
[
'a1' => 13,
'v1' => 2100.00,
'v2' => 386.00,
'v3' => 386.00,
],
[
'a1' => 13,
'v1' => 1200.00,
'v2' => 72.00,
'v3' => 72.00,
]
];
$r = [];
foreach ($a as $item) {
$key = $item['a1'];
if (empty($r[$key]))
$r[$key] = $item;
else {
foreach ($item as $k => $v) {
if ($k !== 'a1')
$r[$key][$k] = empty($r[$key][$k]) ? $item[$k] : $r[$key][$k] + $item[$k];
}
}
}
print_r(array_values($r));
A simple foreach loop can do it.
$result = array();
foreach($yourArray as $arr){
foreach($arr as $i=>$v) {
if(!isset($result[$i])) {
$result[$i] = 0;
}
if($i == 'a1'){
$result[$i] = $v;
} else {
$result[$i] += $v;
}
}
}

How to extract specific key string from array in php?

This is my array
Array
(
[question_set] => Computer Basics
[question] => Who are You ?
[options_1] => RK
[options_2] => KAMAL
[options_3] => DPK
[options_4] => NARENDRA
[marks] => 5
[negative_marks] => 1
[type] => 1
)
options_ are dynamic means it can be 4, 6 or 8.
I want to get value "options" from key of options_1 or so on. How can I do this.
strpos is way faster than preg_match, for reference: strpos() vs preg_match()
Using foreach and strpos() :
$arr = array(
"question_set" => "Computer Basics",
"question" => "Who are You ?",
"options_1" => "RK",
"options_2" => "KAMAL",
"options_3" => "DPK",
"options_4" => "NARENDRA",
"marks" => 5,
"negative_marks" => 1,
"type" => 1
);
$newArr = array();
foreach($arr as $key => $value) {
if(strpos($key, "options") !== false) {
$newArr[$key] = $value;
}
}
echo '<pre>';
var_dump($newArr);
echo '</pre>';
<?php
$array = array("options_1" => "RK",
"options_213" => "21313",
"options_4" => "NARENDRA",
"foo" => "bar", 5 , 5 => 89009,
);
$pattern = "/\boptions/";
foreach($array as $key => $value) {
if (preg_match($pattern,$key)){
echo $key."\t=>\t".$value."\n";
}
}

Shift an element to the end of array

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)

Select arrays with multiple occurence from a array of arrys - PHP

My array is given below. Which contains more than one arrays.
Array
(
[0] => Array
(
[user_id] => 1
[name] => name1
)
[1] => Array
(
[user_id] => 2
[name] => name2
)
[2] => Array
(
[user_id] => 2
[name] => name2
)
[3] => Array
(
[user_id] => 3
[name] => name3
)
)<br/>
I need arrays which has more than one occurence.In this case
Array
(
[user_id] => 2
[name] => name2
)
Try this.
function get_multi_occur($my_array)
{
foreach ($my_array as $id => $a) {
$key = $a[user_id] . $a[name];
if ($s[$key]['cnt'] == 0) {
$s[$key]['cnt'] = 1;
$s[$key]['id'] = $id;
} else {
$s[$key]['cnt']++;
}
}
foreach ($s as $r) {
if ($r['cnt'] >= 2) {
$ret[] = $my_array[$r[id]];
}
}
return $ret;
}
foreach ($array as $key_1=>$sub_array_1)
{
foreach ($array as $key_2=>$sub_array_2)
{
if ($sub_array_1 == $sub_array_2 &&
$key_1 != $key_2)//prevent to compare same sub arrays
print_r($sub_array_1);
}
}
something like this
You can try
$array = Array(
"0" => Array("user_id" => 1,"name" => "name1"),
"1" => Array("user_id" => 2,"name" => "name2"),
"2" => Array("user_id" => 2,"name" => "name2"),
"3" => Array("user_id" => 3,"name" => "name3"));
$d = $s = array();
array_map(function ($v) use(&$d, &$s) {
array_key_exists($v['user_id'], $s) && ! array_key_exists($v['user_id'], $d) ? $d[$v['user_id']] = $v : $s[$v['user_id']] = $v;
}, $array);
var_dump($d);
Output
array
2 =>
array
'user_id' => int 2
'name' => string 'name2' (length=5)
Create a new array that will store data that have same values.
Try this code :
$array_existing = array();
$ctr = 0;
foreach ($first_array as $key => $first) :
foreach ($second_array as $keytwo => $second) :
if ($first['user_id'] == $second['user_id'] && $first['name'] == $second['name']) {
$array_existing[$ctr]['user_id'] = $first['user_id'];
$array_existing[$ctr]['name'] = $first['name'];
$array_existing[$ctr]['first_index'] = $key;
$array_existing[$ctr]['second_index'] = $keytwo;
$ctr++;
}
endforeach;
endforeach;
var_dump($array_existing);

Categories