Why are all indices in an array 0? - php

Why does the following code output 0 indices?
I want the indices to be: 0 1 2 3 4 .... How do I fix it?
Code:
foreach ($query->result() as $row){
$data = json_decode($row->residence,true);
foreach($data as $datum){
$newArray = array_chunk($datum['units'], 3);
foreach($newArray as $newA){
$output = array(implode(",",$newA));
echo print_r($output).'<br>'; //this is output
}
}
}
Output:
Array ( [0] => salam,11,11 ) 1 Array ( [0] => khobe,22,22 ) 1
Array ( [0] => salam,55,55 ) 1 Array ( [0] => khobe,66,66 ) 1
I want this output:
Array ( [0] => salam,11,11 ) 1 Array ( [1] => khobe,22,22 ) 1
Array ( [2] => salam,55,55 ) 1 Array ( [3] => khobe,66,66 ) 1
Update:
My JSON encoded in the database:
[{
"units": ["salam", "11", "11", "khobe", "22", "22"],
}, {
"units": ["salam", "55", "55", "khobe", "66", "66"],
}]

On this line $output = array(implode(",",$newA)); you are creating a new array for each set of results, so the offset with always start at 0.
Try this:
$output = array();
foreach ($query->result() as $row){
$data = json_decode($row->residence,true);
foreach($data as $unit) {
$output[] = implode(',', $unit['units']);
}
}
print_r($output);
I get the following output from a single row:
Array
(
[0] => salam,11,11,khobe,22,22
[1] => salam,55,55,khobe,66,66
)

In the third foreach, you need to add the $output to a new array, then print_r after the loop.
E.g.
foreach ($query->result() as $row){
$data = json_decode($row->residence,true);
foreach($data as $datum){
$newArray = array_chunk($datum['units'], 3);
$count = 0;
foreach($newArray as $newA){
$output = array($count =>implode(",",$newA));
$count++;
print_r($output).'<br>'; //this is output
}
}
}
Or similar.
You might need to move the $count = 0;

Try this instead
$output[] = array(implode(",",$newA));

You can do so by using a standard for loop like this instead of the foreach loop:
for ($i = 0; $i < count($newArray); $i++) {
// ...
}

You are creating all separate arrays every time you call the array function. To add items to the same array, use $output[] = $valueToAdd:
$output = array();
foreach ($query->result() as $row){
$data = json_decode($row->residence,true);
foreach($data as $datum){
$newArray = array_chunk($datum['units'], 3);
foreach($newArray as $newA){
$output[] = implode(",",$newA);
}
}
}
print_r($output).'<br>'; //this is output

Related

Foreach with reference causing array's last element to repeat

I ran into a weird issue and could reproduce it with this snippet:
<?php
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
foreach ($arr as &$item) {
$item[] = $item[0];
}
foreach ($arr as $item) {
print_r($item);
}
It is outputting (notice the last element had been replaced with a copy of its previous one):
Array
(
[0] => 0
[1] => 0
)
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
[1] => 2
)
Array
(
[0] => 2
[1] => 2
)
However, here's the expected result:
Array
(
[0] => 0
[1] => 0
)
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
[1] => 2
)
Array
(
[0] => 3
[1] => 3
)
If I use array_map instead of the first foreach, it works:
<?php
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
$arr = array_map(function ($item) {
$item[] = $item[0];
return $item;
}, $arr);
foreach ($arr as $item) {
print_r($item);
}
Tested under PHP 8.0.0.
What could be causing this difference? Is there something about array pointers I'm missing?
In your first example, the $item variable still holds a reference to the last value of the $arr when the loop is done.
foreach ($arr as &$item) {
$item[] = $item[0];
}
If you use print_r(get_defined_vars()); you can see that there is a key in the array with name item
The behaviour of the double value at the end of the foreach is described here and It is recommended to destroy the specified variables using unset($item)
You can also use a different variable name.
Using array_map, the callback gets a function argument passed by name, which is bound to the function scope.
If you run print_r(get_defined_vars()); after using array_map you can see that there is no key named item
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
/** Output
* $arr = [[0],[1],[2],[3]]
*/
In this foreach loop you are just selecting the existing value of item and setting it into a new index of referenced item
foreach ($arr as &$item) {
$item[] = $item[0];
}
Type of $item is array, $item[0] is referred to its 0 index
$item[] means a new array index inside item that is currently referenced to.

Get only Numeric values from Array in PHP

I have an array that looks something like this:
Array (
[0] => Array ( [country_percentage] => 5 %North America )
[1] => Array ( [country_percentage] => 0 %Latin America )
)
I want only numeric values from above array. I want my final array like this
Array (
[0] => Array ( [country_percentage] => 5)
[1] => Array ( [country_percentage] => 0)
)
How I achieve this using PHP?? Thanks in advance...
When the number is in first position you can int cast it like so:
$newArray = [];
foreach($array => $value) {
$newArray[] = (int)$value;
}
I guess you can loop the 2 dimensional array and use a preg_replace, i.e.:
for($i=0; $i < count($arrays); $i++){
$arrays[$i]['country_percentage'] = preg_replace( '/[^\d]/', '', $arrays[$i]['country_percentage'] );
}
Ideone Demo
Update Based on your comment:
for($i=0; $i < count($arrays); $i++){
if( preg_match( '/North America/', $arrays[$i]['country_percentage'] )){
echo preg_replace( '/[^\d]/', '', $arrays[$i]['country_percentage'] );
}
}
Try this:
$arr = array(array('country_percentage' => '5 %North America'),array("country_percentage"=>"0 %Latin America"));
$result = array();
foreach($arr as $array) {
$int = filter_var($array['country_percentage'], FILTER_SANITIZE_NUMBER_INT);
$result[] = array('country_percentage' => $int);
}
Try this one:-
$arr =[['country_percentage' => '5 %North America'],
['country_percentage' => '0 %Latin America']];
$res = [];
foreach ($arr as $key => $val) {
$res[]['country_percentage'] = (int)$val['country_percentage'];
}
echo '<pre>'; print_r($res);
output:-
Array
(
[0] => Array
(
[country_percentage] => 5
)
[1] => Array
(
[country_percentage] => 0
)
)
You can use array_walk_recursive to do away with the loop,
passing the first parameter of the callback as a reference to modify the initial array value.
Then just apply either filter_var or intval as already mentioned the other answers.
$array = [
["country_percentage" => "5 %North America"],
["country_percentage" => "0 %Latin America"]
];
array_walk_recursive($array, function(&$value,$key){
$value = filter_var($value,FILTER_SANITIZE_NUMBER_INT);
// or
$value = intval($value);
});
print_r($array);
Will output
Array
(
[0] => Array
(
[country_percentage] => 5
)
[1] => Array
(
[country_percentage] => 0
)
)
You could get all nemeric values by looping through the array. However I don't think this is the most efficient and good looking answer, I'll post it anyways.
// Array to hold just the numbers
$newArray = array();
// Loop through array
foreach ($array as $key => $value) {
// Check if the value is numeric
if (is_numeric($value)) {
$newArray[$key] = $value;
}
}
I missunderstood your question.
$newArray = array();
foreach ($array as $key => $value) {
foreach ($value as $subkey => $subvalue) {
$subvalue = trim(current(explode('%', $subvalue)));
$newArray[$key] = array($subkey => $subvalue);
}
}
If you want all but numeric values :
$array[] = array("country_percentage"=>"5 %North America");
$array[] = array("country_percentage"=>"3 %Latin America");
$newArray = [];
foreach ($array as $arr){
foreach($arr as $key1=>$arr1) {
$newArray[][$key1] = intval($arr1);
}
}
echo "<pre>";
print_R($newArray);
This is kind of a ghetto method to doing it cause I love using not as many pre made functions as possible. But this should work for you :D
$array = array('jack', 2, 5, 'gday!');
$new = array();
foreach ($array as $item) {
// IF Is numeric (each item from the array) will insert into new array called $new.
if (is_numeric($item)) { array_push($new, $item); }
}

combine arrays and concat value?

Little complex to explain , so here is simple concrete exemple :
array 1 :
Array
(
[4] => bim
[5] => pow
[6] => foo
)
array 2 :
Array
(
[n] => Array
(
[0] => 1
)
[m] => Array
(
[0] => 1
[1] => 2
)
[l] => Array
(
[0] => 1
[1] => 4
[2] => 64
)
And i need to output an array 3 ,
array expected :
Array
(
[bim] => n-1
[pow] => Array
(
[0] => m-1
[1] => m-2
)
[foo] => Array
(
[0] => l-1
[1] => l-4
[2] => l-64
)
Final echoing OUTPUT expected:
bim n-1 , pow m-1 m-2 ,foo l-1 l-4 l-64 ,
I tried this but seems pity:
foreach($array2 as $k1 =>$v1){
foreach($array2[$k1] as $k => $v){
$k[] = $k1.'_'.$v);
}
foreach($array1 as $res =>$val){
$val = $array2;
}
Thanks for helps,
Jess
CHALLENGE ACCEPTED
<?php
$a = array(
4 => 'bim',
5 => 'pow',
6 => 'foo',
);
$b = array(
'n' => array(1),
'm' => array(1, 2),
'l' => array(1, 4, 64),
);
$len = count($a);
$result = array();
$aVals = array_values($a);
$bKeys = array_keys($b);
$bVals = array_values($b);
for ($i = 0; $i < $len; $i++) {
$combined = array();
$key = $aVals[$i];
$prefix = $bKeys[$i];
$items = $bVals[$i];
foreach ($items as $item) {
$combined[] = sprintf('%s-%d', $prefix, $item);
};
if (count($combined) === 1) {
$combined = $combined[0];
}
$result[$key] = $combined;
}
var_dump($result);
?>
Your code may be very easy. For example, assuming arrays:
$one = Array
(
4 => 'bim',
5 => 'pow',
6 => 'foo'
);
$two = Array
(
'n' => Array
(
0 => 1
),
'm' => Array
(
0 => 1,
1 => 2
),
'l' => Array
(
0 => 1,
1 => 4,
2 => 64
)
);
You may get your result with:
$result = [];
while((list($oneKey, $oneValue) = each($one)) &&
(list($twoKey, $twoValue) = each($two)))
{
$result[$oneValue] = array_map(function($item) use ($twoKey)
{
return $twoKey.'-'.$item;
}, $twoValue);
};
-check this demo Note, that code above will not make single-element array as single element. If that is needed, just add:
$result = array_map(function($item)
{
return count($item)>1?$item:array_shift($item);
}, $result);
Version of this solution for PHP4>=4.3, PHP5>=5.0 you can find here
Update: if you need only string, then use this (cross-version):
$result = array();
while((list($oneKey, $oneValue) = each($one)) &&
(list($twoKey, $twoValue) = each($two)))
{
$temp = array();
foreach($twoValue as $item)
{
$temp[] = $twoKey.'-'.$item;
}
$result[] = $oneValue.' '.join(' ', $temp);
};
$result = join(' ', $result);
As a solution to your problem please try executing following code snippet
<?php
$a=array(4=>'bim',5=>'pow',6=>'foo');
$b=array('n'=>array(1),'m'=>array(1,2),'l'=>array(1,4,64));
$keys=array_values($a);
$values=array();
foreach($b as $key=>$value)
{
if(is_array($value) && !empty($value))
{
foreach($value as $k=>$val)
{
if($key=='n')
{
$values[$key]=$key.'-'.$val;
}
else
{
$values[$key][]=$key.'-'.$val;
}
}
}
}
$result=array_combine($keys,$values);
echo '<pre>';
print_r($result);
?>
The logic behind should be clear by reading the code comments.
Here's a demo # PHPFiddle.
//omitted array declarations
$output = array();
//variables to shorten things in the loop
$val1 = array_values($array1);
$keys2 = array_keys($array2);
$vals2 = array_values($array2);
//iterating over each element of the first array
for($i = 0; $i < count($array1); $i++) {
//if the second array has multiple values at the same index
//as the first array things will be handled differently
if(count($vals2[$i]) > 1) {
$tempArr = array();
//iterating over each element of the second array
//at the specified index
foreach($vals2[$i] as $val) {
//we push each element into the temporary array
//(in the form of "keyOfArray2-value"
array_push($tempArr, $keys2[$i] . "-" . $val);
}
//finally assign it to our output array
$output[$val1[$i]] = $tempArr;
} else {
//when there is only one sub-element in array2
//we can assign the output directly, as you don't want an array in this case
$output[$val1[$i]] = $keys2[$i] . "-" . $vals2[$i][0];
}
}
var_dump($output);
Output:
Array (
["bim"]=> "n-1"
["pow"]=> Array (
[0]=> "m-1"
[1]=> "m-2"
)
["foo"]=> Array (
[0]=> "l-1"
[1]=> "l-4"
[2]=> "l-64"
)
)
Concerning your final output you may do something like
$final = "";
//$output can be obtained by any method of the other answers,
//not just with the method i posted above
foreach($output as $key=>$value) {
$final .= $key . " ";
if(count($value) > 1) {
$final .= implode($value, " ") .", ";
} else {
$final .= $value . ", ";
}
}
$final = rtrim($final, ", ");
This will echo bim n-1, pow m-1 m-2, foo l-1 l-4 l-64.

PHP Array output from result array values

Below is my result array:
Array
(
[0] => Array
(
[id] => 3
[name] => test
)
[1] => Array
(
[id] => 4
[name] => Balikavadhu
)
)
From above array, I want to generate a new array as below:
array(3,4) // where 3 and 4 are id values of respective array
Any help or quick answer will be appreciated.
Thanks in advance !
Yet another option:
$newArray = [];
foreach ($arrayResults as $result) {
$newArray[] = $result['id'];
}
Put your output array into an array called $arr. Then do this :
$newArr = array();
$id = 0;
foreach ($arr as $val)
{
$newArr[$i] = $val['id'];
$id++;
}
You could do something like
$newArray = [];
foreach ($arrayResults as $result) {
array_push($newArray, $result['id']);
}

Merge 3 rows that have json value

I have in a database table 3 rows that are json data and i want them merge they in a array, how can fix it?
Row 1 : ["11,22,13"]
Row 2 : ["48"]
Row 3 : ["53,67,70"]
I want in output as: array(11,22,13,48,53,67,70)
My tried as:
$result = $this->db->get_where('table',array('mainpage'=>$mp'));
$data = array();
foreach($result->result() as $row){
$dv = json_decode($row->sbouy);
$out = array();
foreach($dv as $idx => $val){
$out[] = $val;
}
echo '<pre>';
print_r($out); // This is not what I want output
}
In my code output is as(This is not what I want output):
Array
(
[0] => 11,22,13
)
Array
(
[0] => 48
)
Array
(
[0] => 53,67,70
)
Use this
$data = array();
$out = array();
foreach($result->result() as $row){
$dv = json_decode($row->sbouy);
foreach($dv as $idx => $val){
$out[] = $val;
}
}
echo '<pre>';
print_r($out); // This is what you want :)
You have to define $out outside foreach. Instead of loop you can even use array_merge

Categories