Result saves in two arrays - php

I'm playing around with foreach and Simple HTML dom there I'm trying to save down some links to a array. But my problem is that the result saves in two arrays instead of one array.
foreach($html->find('div[class^=voucher success]') as $q)
{
#$var = $q->find('a', 0)->href;
$pos = strpos($var, "/ut/");
if($pos === false)
{
$item[] = $var;
}
var_dump($item);
}
Dump:
array(1) {
[0]=> string(10) "/hm?v=2726" }
array(2) {
[0]=> string(10) "/hm?v=2726" [1]=> string(10) "/hm?v=2732"
}
Why is that? What have I done wrong?

It's not saving in two arrays. You're dumping the data at the end of every foreach loop. Therefore it dumps twice, because there is two loops in the foreach.
To see the final result of $item you need to dump after the foreach.
foreach($html->find('div[class^=voucher success]') as $q)
{
#$var = $q->find('a', 0)->href;
$pos = strpos($var, "/ut/");
if($pos === false)
{
$item[] = $var;
}
}
var_dump($item);
The output would now be:
array(2) {
[0]=> string(10) "/hm?v=2726" [1]=> string(10) "/hm?v=2732"
}

Why do you think it is in two arrays? Your var_dump is inside your loop, so it is just dumping each time you iterate.

Related

Recursive function for checking multidimensional arrays

Really struggling with this. I have a multidimensional array n levels deep. Each 'array level' has information I need to check (category) and also check if it contains any arrays.
I want to return the category ids of all the arrays which have a category and do not contain an array (i.e. the leaves). I can echo output properly, but I am at a loss as how to return the ids in an array (without referencing)
I have tried RecursiveIteratorIterator::LEAVES_ONLY and RecursiveArrayIterator but I don't think they work in my case? (Maybe I am overlooking something)
$array
array(2) {
["1"]=>
string(5) "stuff"
["2"]=>
array(2) {
["category"]=>
string(1) "0"
["1"]=>
array(3) {
[0]=>
array(3) {
["category"]=>
string(1) "1"
["1"]=>
string(5) "stuff"
["2"]=>
string(5) "stuff"
}
[1]=>
array(5) {
["category"]=>
string(1) "2"
["1"]=>
string(5) "stuff"
["2"]=>
string(5) "stuff"
}
[1]=>
array(5) {
["1"]=>
string(5) "stuff"
["32"]=>
string(5) "stuff"
}
}
}
}
My function
public function recurs($array, $cats = [])
{
$array_cat = '';
$has_array = false;
// Check if an id exists in the array
if (array_key_exists('category', $array)) {
$array_cat = $array['category'];
}
// Check if an array exists within the array
foreach ($array as $key => $value) {
if (is_array($value)) {
$has_array = true;
$this->recurs($value, $cats);
}
}
// If a leaf array
if (!$has_array && is_numeric($array_cat)) {
echo "echoing the category here works fine: " . $array_cat . "\n";
return $array_cat;
}
}
Calling it
$cats_array = $this->recurse($array)
Output echoed
echoing the category here works fine: 1
echoing the category here works fine: 2
How do I return the ids in an array to use in the $cats_array variable?
EDIT: The output should match the echo, so I should get an array containing (1, 2) since they are the only arrays with categories and no arrays within them
array(2){
[0]=>
int(1) "1"
[1]=>
int(1) "2"
}
If I understood you correctly this function will do the job:
function getCategories(array $data)
{
if ($subArrays = array_filter($data, 'is_array')) {
return array_reduce(array_map('getCategories', $subArrays), 'array_merge', array());
};
return array_key_exists('category', $data) ? array($data['category']) : array();
}
If the array contains any sub-arrays they will be returned by array_filter and you will enter the if statement. array_map will apply the function recursively to the sub-arrays and array_reduce will merge the results.
If the array doesn't contain any sub-arrays you will not enter the if statement and the function will return an array with the category if it is present.
Note that you might need to use array_unique to return unique categories.
Also for small performance optimization instead of array_key_exists you can use isset($array[$key]) || array_key_exists($key, $array).
Update
If you want to update your function to make it work you have to recursively collect and merge the sub results. In the following example I introduced a new variable for this:
public function recurs($array, $cats = [])
{
$result = [];
$array_cat = '';
$has_array = false;
// Check if an id exists in the array
if (array_key_exists('category', $array)) {
$array_cat = $array['category'];
}
// Check if an array exists within the array
foreach ($array as $key => $value) {
if (is_array($value)) {
$has_array = true;
$result = array_merge($result, $this->recurs($value, $cats));
}
}
// If a leaf array
if (!$has_array && is_numeric($array_cat)) {
echo "echoing the category here works fine: " . $array_cat . "\n";
return [$array_cat];
}
return $result;
}

How to edit mulltidimensional array elements in php?

this is my array:
$array= array(3) {
[0]=> array(3) { ["name"]=> "one" ["com"]=> "com1" ["id"]=> "1" }
[1]=> array(3) { ["name"]=> "two" ["com"]=> "com2" ["id"]=> "2" }
[2]=> array(3) { ["name"]=> "three" ["com"]=> "com3" ["id"]=> "3" }
I need posibility to change values of name and com for specific id. I try some examples from Stack questions:
1.Link1
foreach($array as &$value){
if($value['id'] == 1){
$value['name'] = 'test';
$value['com'] = 'test';
break; // Stop the loop after we've found the item
}
}
But it don't work. no error but no result too.
2.Link 2
Again,no error message,but no result...
I also try a lot of other examples from Stack but fake,and finaly to write a question..
Buy,
P
Since you are not changing your array value that's why it's-not giving you desired output. Try this:-
foreach($array as $key => &$value){
if($key == 1){
$array[1]['name'] = 'test';// change value to original array
$array[1]['com'] = 'test'; //change value to original array
break; // Stop the loop after we've found the item
}
}
for($i=0;$i<count($array);$i++) {
if($array[$i]['id'] == 1) {
$array[$i]['name'] = 'test';
$array[$i]['com'] = '';
break;
}
}
print_r($array);
If you are able to change the array on creation I would recommend shifting the id to the array's key identifier. Would make life a lot easier to just do:
$array[1]['name'] = 'test';
Otherwise use the for loop posted above and look it up. (Right awnser)

PHP Creating an array from an array and looping through

I have the following code:
foreach ($row as $item) {
if (!in_array($item['login_id'], $tmp)) {
$tmp[] = $item['brand'];
$tmp[] = $item['login_id'];
$tmp[] = $item['name'];
}
}
This provides the following output:
array(408) {
[0]=> string(4) "ABC"
[1]=> string(8) "r4ft6tg7"
[2]=> string(8) "Aberdeen"
[3]=> string(4) "ABC"
[4]=> string(8) "1ws3edft"
[5]=> string(18) "Birmingham Airport"
[6]=> string(4) "DDD"
[7]=> string(8) "bgt6yhnj"
[8]=> string(27) "Birmingham City"...}
I am trying to then loop through this array and add them to a dropdown using the following:
$a = 0;
$b = 1;
$c = 2;
foreach ($tmp as $value) {
echo "<option name='".$value[$a]."'
value='".$value[$b]."'>
".$value[$c]."
</option>";
$a=$a+3;
$b=$b+3;
$c=$c+3;
}
However the output is most odd:
<option name='I' value='b'>i</option>
The output I expected and need is:
<option name='ABC' value='r4ft6tg7'>Aberdeen</option>
Any suggestions, feedback on where I am going wrong would be appreciated.
I believe this is what you meant:
foreach ($row as $item) {
if (! array_key_exists($item['login_id'], $tmp)) {
$tmp[$item['login_id']] = array($item['brand'], $item['login_id'], $item['name']);
}
}
EDIT: Fixed index of $tmp above (and how to check for index).
Then your following code could work the same, omitting the increments of $a, $b, $c (and hence omitting those three variables altogether):
foreach ($tmp as $value) {
echo "<option name='".$value[0]."'
value='".$value[1]."'>
".$value[2]."
</option>";
}
You were mistakenly treating $tmp as both a one- and two-dimensional array. Actually setting it up to be a two-dimensional array resolves that. As pointed out in the comments, in your original code, $value was a string, and accessing an index of a string like you would an array yields the given character in the string.
Also, for clarity, you might consider making each subarray in $tmp an asssociative array.
E.g.
$tmp[$item['login_id']] = array('brand' => $item['brand'], ... and then accessing it accordingly in your latter foreach loop.

Changes to array of JSON objects based on other array

I have an array of JSON objects that look like this:
{"id":1,"place":2,"pic_name":"aaa.jpg"}
My PHP file receives a simple array like:
["4","3","1","2","5"]
These numbers correspond to the place value in my JSON object. Now I need to compare the place of each element in the secont array with the value of ID in the JSON object and if the match I have to replace the value of PLACE with the element from the array.
I am having problems doing the comparison. Any guidelines? What I come up with:
foreach($ids as $index=>$id) { //the array
$id = (int) $id;
foreach ($obj as $key=>$value) { //the JSON objects
foreach ($value as $k=>$v){
if ($id != '' && array_search($index, array_keys($ids)) == $value[$k]['id']) {
$value[$k]['place'] = $id;
file_put_contents($file, json_encode($ids));
} else { print "nope";}
} } }
That will be:
$array = [
'{"id":1,"place":2,"pic_name":"aaa.jpg"}',
'{"id":2,"place":5,"pic_name":"aab.jpg"}',
'{"id":3,"place":1,"pic_name":"aba.jpg"}',
'{"id":4,"place":3,"pic_name":"baa.jpg"}',
'{"id":5,"place":4,"pic_name":"abb.jpg"}'
];
$places = ["4","3","1","2","5"];
$array = array_map(function($item)
{
return json_decode($item, 1);
}, $array);
foreach($array as $i=>$jsonData)
{
if(false!==($place=array_search($jsonData['id'], $places)))
{
$array[$i]['place'] = $place+1;
}
}
$array = array_map('json_encode', $array);
//var_dump($array);
-with output like:
array(5) {
[0]=>
string(39) "{"id":1,"place":3,"pic_name":"aaa.jpg"}"
[1]=>
string(39) "{"id":2,"place":4,"pic_name":"aab.jpg"}"
[2]=>
string(39) "{"id":3,"place":2,"pic_name":"aba.jpg"}"
[3]=>
string(39) "{"id":4,"place":1,"pic_name":"baa.jpg"}"
[4]=>
string(39) "{"id":5,"place":5,"pic_name":"abb.jpg"}"
}

Remove element from array if string contains any of the characters

Remove element from array if string contains any of the characters.For example Below is the actual array.
array(1390) {
[0]=>
string(9) "Rs.52.68""
[1]=>
string(20) ""php code generator""
[2]=>
string(9) ""Rs.1.29""
[3]=>
string(21) ""php codes for login""
[4]=>
string(10) ""Rs.70.23""
}
I need the array to remove all the elements which start with RS.
Expected Result
array(1390) {
[0]=>
string(20) ""php code generator""
[1]=>
string(21) ""php codes for login""
}
What i tried so far :
foreach($arr as $ll)
{
if (strpos($ll,'RS.') !== false) {
echo 'unwanted element';
}
From above code how can i remove unwanted elements from array .
You can get the $key in the foreach loop and use unset() on your array:
foreach ($arr as $key => $ll) {
if (strpos($ll,'RS.') !== false) {
unset($arr[$key]);
}
}
Note that this would remove none of your items as "RS" never appears. Only "Rs".
This sounds like a job for array_filter. It allows you to specify a callback function that can do any test you like. If the callback returns true, the value if returned in the resulting array. If it returns false, then the value is filtered out.
$arr = array_filter($arr,
function($item) {
return strpos($item, 'Rs.') === false;
});
Rs is different than RS you want to use stripos rather than strpos for non case sensitive checking
foreach($arr as $key => $ll)
{
if (stripos($ll,'RS.') !== false) {
unset($arr[$key]);
}
}
or use arrayfilter as pointed out

Categories