How would I iterate through an array (300+ items, imported via simplexml) and pull out every item that has a certain $x->channel->item->title and put that into a different array?
I can't make heads or tails of the haystack needle thing or how to push arrays
Say I have an array (needle) like: array("3332","3300","3493","8380") and I want to match if any of those appear through the big array (haystack). How do I do this?
You have to iterate over your big array, and check for the value of $x->channel->item->title. If it meets your criteria, push it into the new array:
$theArray; // Your 300+ array
$lookFor = array('firstthing', 'second thing', 'third thing');
$newArray = array();
foreach($theArray as $x) {
if ( in_array($x->channel->item->title, $lookFor) ) {
array_push($newArray, $x);
}
}
foreach($yourArray as $key => $value)
{
//do your things with $key and/or $value
}
Modifying from Joseph's loop, you can do:
$theArray; // Your 300+ array
$newArray = array();
$matchArray = array("3332","3300","3493","8380");
foreach($theArray as $x) {
if (in_array($x->channel->item->title, $matchArray)) {
array_push($newArray, $x);
}
}
Check out in_array() at http://php.net/manual/en/function.in-array.php
Related
I have an array like this,
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
I want to find any value with an ">" and replace it with a range().
The result I want is,
array(
1,2,3,4,5,6,7,8,9,10,11,12, '13.1', '13.2', 14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
);
My understanding:
if any element of $array has '>' in it,
$separate = explode(">", $that_element);
$range_array = range($separate[0], $separate[1]); //makes an array of 4 to 12.
Now somehow replace '4>12' of with $range_array and get a result like above example.
May be I can find which element has '>' in it using foreach() and rebuild $array again using array_push() and multi level foreach. Looking for a more elegant solution.
You can even do it in a one-liner like this:
$array = array(1,2,3,'4>12','13.1','13.2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,#range(...array_slice(explode(">","$c>$c"),0,2)));},
[]
));
I avoid any if clause by using range() on the array_slice() array I get from exploding "$c>$c" (this will always at least give me a two-element array).
You can find a little demo here: https://rextester.com/DXPTD44420
Edit:
OK, if the array can also contain non-numeric values the strategy needs to be modified: Now I will check for the existence of the separator sign > and will then either merge some cells created by a range() call or simply put the non-numeric element into an array and merge that with the original array:
$array = array(1,2,3,'4>12','13.1','64+2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,strpos($c,'>')>0?range(...explode(">",$c)):[$c]);},
[]
));
See the updated demo here: https://rextester.com/BWBYF59990
It's easy to create an empty array and fill it while loop a source
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$res = [];
foreach($array as $x) {
$separate = explode(">", $x);
if(count($separate) !== 2) {
// No char '<' in the string or more than 1
$res[] = $x;
}
else {
$res = array_merge($res, range($separate[0], $separate[1]));
}
}
print_r($res);
range function will help you with this:
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$newArray = [];
foreach ($array as $item) {
if (strpos($item, '>') !== false) {
$newArray = array_merge($newArray, range(...explode('>', $item)));
} else {
$newArray[] = $item;
}
}
print_r($newArray);
I have two arrays namely arr and arr2.
var arr=[{"month":"January","url":1},{"month":"February","url":102},{"month":"March","url":192}];
var arr2=[{"month":"January","ip":12},{"month":"June","ip":10}];
Is it possible to get array below shown from above two arrays?
result=[{"month":"January","url":1,"ip":12},{"month":"February","url":102},{"month":"March","url":192},{"month":"June","ip":10}];
If i use array_merge then i get answer as
result=[{"month":"January","url":1},{"month":"February","url":102},{"month":"March","url":192},{"month":"January","ip":12},{"month":"June","ip":10}];
You must decode JSON to arrays, manually merge them and again encode it to JSON :)
<?php
$arr = json_decode('[{"month":"January","url":1},{"month":"February","url":102},{"month":"March","url":192}]', true);
$arr2 = json_decode('[{"month":"January","ip":12},{"month":"June","ip":10}]', true);
$result = [];
foreach ($arr as &$item) {
if (empty($arr2))
break;
foreach ($arr2 as $key => $item2) {
if ($item['month'] === $item2['month']) {
$item = array_merge($item, $item2);
unset($arr2[$key]);
continue;
}
}
}
if (!empty($arr2))
$arr = array_merge($arr, $arr2);
echo json_encode($arr);
The first function that comes to mind is array_merge_recursive(), but even if you assign temporary associative keys to the subarrays, you end up with multiple January values in a new deep subarray.
But do not despair, there is another recursive function that can do this job. array_replace_recursive() will successfully merge these multidimensional arrays so long as temporary associative keys are assigned first.
Here is a one-liner that doesn't use foreach() loops or if statements:
Code: (Demo)
$arr=json_decode('[{"month":"January","url":1},{"month":"February","url":102},{"month":"March","url":192}]',true);
$arr2=json_decode('[{"month":"January","ip":12},{"month":"June","ip":10}]',true);
echo json_encode(array_values(array_replace_recursive(array_column($arr,NULL,'month'),array_column($arr2,NULL,'month'))));
Output:
[{"month":"January","url":1,"ip":12},{"month":"February","url":102},{"month":"March","url":192},{"month":"June","ip":10}]
The breakdown:
echo json_encode( // convert back to json
array_values( // remove the temp keys (reindex)
array_replace_recursive( // effectively merge/replace elements associatively
array_column($arr,NULL,'month'), // use month as temp keys for each subarray
array_column($arr2,NULL,'month') // use month as temp keys for each subarray
)
)
);
You should write your own function to do that
$res = [];
foreach ($arr as $item) {
$res[$item['month']] = $item;
}
foreach ($arr2 as $item) {
$res[$item['month']] = isset($res[$item['month']]) ? array_merge($res[$item['month']], $item) : $item;
}
var_dump($res);
I have following array of arrays:
$array = [
[A,a,1,i],
[B,b,2,ii],
[C,c,3,iii],
[D,d,4,iv],
[E,e,5,v]
];
From this one, I would like to create another array where the values are extract only if the value of third key of each subarray is, for example, greater than 3.
I thought in something like that:
if $array['2'] > 3){
$new_array[] = [$array['0'],$array['2'],$array['3']];
}
So in the end we would have following new array (note that first keys of the subarrays were eliminate in the new array):
$new_array = [
[D,4,iv],
[E,5,v]
];
In general, I think it should be made with foreach, but on account of my descripted problem I have no idea how I could do this. Here is what I've tried:
foreach($array as $value){
foreach($value as $k => $v){
if($k['2'] > 3){
$new_array[] = [$v['0'], $v['2'], $v['3']];
}
}
}
But probably there's a native function of PHP that can handle it, isn't there?
Many thanks for your help!!!
Suggest you to use array_map() & array_filter(). Example:
$array = [
['A','a',1,'i'],
['B','b',2,'ii'],
['C','c',3,'iii'],
['D','d',4,'iv'],
['E','e',5,'v']
];
$newArr = array_filter(array_map(function($v){
if($v[2] > 3) return [$v[0], $v[2], $v[3]];
}, $array));
print '<pre>';
print_r($newArr);
print '</pre>';
Reference:
array_map()
array_filter()
In the first foreach, $v is the array you want to test and copy.
You want to test $v[2] and check if it match your condition.
$new_array = [];
foreach($array as $v) {
if($v[2] > 3) {
$new_array[] = [$v[0], $v[2], $v[3]];
}
}
Is there any way that I can remove the successive duplicates from the array below while only keeping the first one?
The array is shown below:
$a=array("1"=>"go","2"=>"stop","3"=>"stop","4"=>"stop","5"=>"stop","6"=>"go","7"=>"go","8"=>"stop");
What I want is to have an array that contains:
$a=array("1"=>"go","2"=>"stop","3"=>"go","7"=>"stop");
Successive duplicates? I don't know about native functions, but this one works. Well almost. Think I understood it wrong. In my function the 7 => "go" is a duplicate of 6 => "go", and 8 => "stop" is the new value...?
function filterSuccessiveDuplicates($array)
{
$result = array();
$lastValue = null;
foreach ($array as $key => $value) {
// Only add non-duplicate successive values
if ($value !== $lastValue) {
$result[$key] = $value;
}
$lastValue = $value;
}
return $result;
}
You can just do something like:
if(current($a) !== $new_val)
$a[] = $new_val;
Assuming you're not manipulating that array in between you can use current() it's more efficient than counting it each time to check the value at count($a)-1
This is what I have tried:
foreach ($multiarr as $arr) {
foreach ($arr as $key=>$val) {
if (next($arr) === false) {
//work on last key
} else {
//work
}
}
}
After taking another look, I thinknext is being used wrong here, but I am not sure what to do about it.
Is it possible to see if I'm on the last iteration of this array?
$lastkey = array_pop(array_keys($arr));
$lastvalue = $arr[$lastkey];
If you want to use it in a loop, just compare $lastkey to $key
You will need to keep a count of iterations and check it against the length of the array you are iterating over. The default Iterator implementation in PHP does not allow you to check whether the next element is valid -- next has a void return and the api only exposes a method to check whether the current position is valid. See here http://php.net/manual/en/class.iterator.php. To implement the functionality you are thinking about you would have to implement your own iterator with a peek() or nextIsValid() method.
Try this:
foreach ($multiarr as $arr) {
$cnt=count($arr);
foreach ($arr as $key=>$val) {
if (!--$cnt) {
//work on last key
} else {
//work
}
}
}
See below url i think it help full to you:-
How to get last key in an array?
How to get last key in an array?
Update:
<?php
$array = array(
array(
'first' => 123,
'second' => 456,
'last' => 789),
array(
'first' => 123,
'second' => 456,
'last_one' => 789),
);
foreach ($array as $arr) {
end($arr); // move the internal pointer to the end of the array
$key = key($arr); // fetches the key of the element pointed to by the internal pointer
var_dump($key);
}
output:
string(4) "last" string(4) "last_one"
This function (in theory, I haven't tested it) will return the last and deepest key in a multidemnsional associative array. Give I a run, I think you'll like it.
function recursiveEndOfArrayFinder($multiarr){
$listofkeys = array_keys($multiarr);
$lastkey = end($listofkeys);
if(is_array($multiarr[$lastkey])){
recursiveEndOfArrayFinder($multiarr[$lastkey]);
}else{
return $lastkey;
}
}