I'm trying to solve an issue where I have an multilevel array that needs to be filtered with user controlled filters.
Example of the array
[1] => Array
(
[objectID] => 5038
[Data] => Array
(
[originalId] => 6
)
[titles] => InfoType Object
(
[_] => string
[language] => eng
)
)
The filters would be then language and objectID, for example.
Anything that doesn't meet the criteria will have to be excluded. Sounds perfectly find if that would be a SQL query, but it's not. The API returns a string that cannot be controlled and it's in a form of an array. Have to work with what you have.
The idea came up to write a function that would prepare an if-statement. Problem is that you can't do just that
foreach ($cache as $listing) {
foreach ($filters as $filter_param => $filter_value) {
if ($query) $output[] = $listing;
}
}
In this case the $query would be equal to something like this:
$listing["titles"]["language"] =="eng" && $listing["objectID"] =="5038"
I'm pretty sure there's an easier way that wouldn't actually be bad. Really stuck with this one.
function isGood($what, $filters) {
foreach ($filters as $key => $value) {
if (is_array($value)) {
if (isGood($what[$key], $value) === false) {
return false;
}
} else {
if ($what[$key] != $value) {
return false;
}
}
}
return true;
}
foreach($cache as $listing) {
if (isGood($listing, $filters)) {
$output[] = $listing;
}
}
Related
How can i add element to my array under a specific key?
This is my array output before i use foreach. As you can see, the error field is empty. I want to fill it out.
Array (
[0] => Array (
[transactionid] => 2223
[created] => 26-02-13 14:07:00
[cardid] => 10102609
[pricebefordiscount] => 68900
[error] =>
)
This is my foreach. As you can see i already tried to make this work by implementing $arrayname['index'] = $value;. But this does not work, nothing comes out when i spit out in a print_r. Why is this happening?
foreach ($samlet as $key)
{
if ($key['pricebefordiscount'] > '200000')
{
$samlet['error'] = "O/2000";
}
if ($key['cardid'] === '88888888')
{
$samlet['error'] = "Testscan";
}
}
This is the desired output:
Array (
[0] => Array (
[transactionid] => 2223
[created] => 26-02-13 14:07:00
[cardid] => 10102609
[pricebefordiscount] => 68900
[error] => "Testscan"
)
Change your foreach, so you have the indexes used in the "main" $samlet array:
foreach($samlet as $key => $array)
{
if ($array['cardid'] === '88888888')
{
$samlet[$key]['error'] = '0/2000';
}
}
And so on...
Try this :
foreach ($samlet as &$key){
if ($key['pricebefordiscount'] > '200000'){
$key['error'] = "O/2000";
}
if ($key['cardid'] === '88888888'){
$key['error'] = "Testscan";
}
}
According to PHP manual:
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
So your code should looke like this:
<?php
foreach ($samlet as &$key)
{
if ($key['pricebefordiscount'] > '200000')
{
$key['error'] = "O/2000";
}
if ($key['cardid'] === '88888888')
{
$key['error'] = "Testscan";
}
}
TRY THIS
foreach ($samlet as $key=>$value)
{
if ($value['pricebefordiscount'] > '200000')
{
$samlet[$key]['error'] = "O/2000";
}
if ($value['cardid'] === '88888888')
{
$samlet[$key]['error'] = "Testscan";
}
}
Here is print_r output of my array:
Array
(
[0] => stdClass Object
(
[itemId] => 560639000019
[name] => Item no1
[code] => 00001
[qty] => 5
[id] => 2
)
[1] => stdClass Object
(
[itemId] => 470639763471
[name] => Second item
[code] => 76347
[qty] => 9
[id] => 4
)
[2] => stdClass Object
(
[itemId] => 56939399632
[name] => Item no 3
[code] => 39963
[qty] => 6
[id] => 7
)
)
How can I find index of object with [id] => 4 in order to remove it from array?
$found = false;
foreach($values as $key => $value) {
if ($value->id == 4) {
$found = true;
break;
}
}
if ($found) unset($values[$key]);
This is considered to be faster then any other solution since we only iterate the array to until we find the object we want to remove.
Note: You should not remove an element of an array while iterating so we do it afterwards here.
foreach($parentObj AS $key=>$element){
if ($element->id == THE_ID_YOU_ARE_LOOKING_FOR){
echo "Gottcha! The index is - ". $key;
}
}
$parentObj is obviously your root array - the one that holds all the others.
We use the foreach loop to iterate over each item and then test it's id property against what ever value you desire. Once we have that - the $key that we are on is the index you are looking for.
use array_search:
$a = new stdClass;
$b = new stdClass;
$a->id = 1;
$b->id = 2;
$arr = array($a, $b);
$index = array_search($b, $arr);
echo $index;
// prints out 1
try this
foreach($array AS $key=>$object){
if($object['id'] == 4){
$key_in_array = $key;
}
}
// chop it from the original array
array_slice($array, $key_in_array, 1);
Another way to achieve the result is to use array_filter.
$array = array(
(object)array('id' => 5),
(object)array('id' => 4),
(object)array('id' => 3)
);
$array = array_filter($array, function($item) {
return $item->id != 4;
});
print_r($array);
Here's my solution. Given, it is a bit hackish, but it will get the job done.
search(array $items, mixed $id[, &$key]);
Returns the item that was found by $id. If you add the variable $key it will give you the key of the item found.
function search($items, $id, &$key = null) {
foreach( $items as $item ) {
if( $item->id == $id ) {
$key = key($item);
return $item;
break;
}
}
return null;
}
Usage
$item = search($items, 4, $key);
unset($items[$key]);
Note: This could be modified to allow a custom key and return multiple items that share the same value.
I've created an example so you can see it in action.
A funny alternative
$getIdUnset = function($id) use ($myArray)
{
foreach($myArray as $key => $obj) {
if ($obj->id == $id) {
return $key;
}
}
return false;
};
if ($unset = $getIdUnset(4)) {
unset($myArray[$unset]);
}
Currently php does not have any supported function for this yet.
So refer to Java's Vector, or jQuery's $.inArray(), it would simply be:
public function indexOf($object, array $elementData) {
$elementCount = count($elementData);
for ($i = 0 ; $i < $elementCount ; $i++){
if ($object == $elementData[$i]) {
return $i;
}
}
return -1;
}
You can save this function as a core function for later.
In my case, this my array as $array
I was confused about this problem of my project, but some answer here helped me.
array(3) {
[0]=> float(-0.12459619130796)
[1]=> float(-0.64018439966448)
[2]=> float(0)
}
Then use if condition to stop looping
foreach($array as $key => $val){
if($key == 0){ //the key is 0
echo $key; //find the key
echo $val; //get the value
}
}
I know, after so many years this could be a useless answer, but why not?
This is my personal implementation of a possible index_of using the same code as other answers but let the programmer to choose when and how the check will be done, supporting also complex checks.
if (!function_exists('index_of'))
{
/**
* #param iterable $haystack
* #param callable $callback
* #param mixed|null &$item
* #return false|int|string
*/
function index_of($haystack, $callback, &$item = null)
{
foreach($haystack as $_key => $_item) {
if ($callback($_item, $_key) === true) {
$item = $_item;
return $_key;
}
}
return false;
}
}
foreach( $arr as $k=>&$a) {
if( $a['id'] == 4 )
unset($arr[$k]);
}
I've trawled the site and the net and have tried various recursive functions etc to no avail, so I'm hoping someone here can point out where I'm going wrong :)
I have an array named $meetingArray with the following values;
Array (
[0] => Array (
[Meet_ID] => 9313
[Meet_Name] => 456136
[Meet_CallInNumber] =>
[Meet_AttendeeCode] =>
[Meet_Password] =>
[Meet_ScheduledDateTime] => 2011-07-18 16:00:00
[Meet_ModeratorCode] =>
[Meet_RequireRegistration] => 0
[Meet_CurrentUsers] => 0
)
[1] => Array (
[Meet_ID] => 9314
[Meet_Name] => 456120
[Meet_CallInNumber] =>
[Meet_AttendeeCode] =>
[Meet_Password] =>
[Meet_ScheduledDateTime] => 2011-07-18 16:00:00
[Meet_ModeratorCode] =>
[Meet_RequireRegistration] => 0
[Meet_CurrentUsers] => 0
)
)
I also have a variable named $meetID.
I want to know if the value in $meetID appears in [Meet_Name] within the array and simply evaluate this true or false.
Any help very much appreciated before I shoot myself :)
function multi_in_array($needle, $haystack, $key) {
foreach ($haystack as $h) {
if (array_key_exists($key, $h) && $h[$key]==$needle) {
return true;
}
}
return false;
}
if (multi_in_array($meetID, $meetingArray, 'Meet_Name')) {
//...
}
I am unsure what you mean by
$meetID appears in [Meet_Name]
but simply substitute the $h[$key]==$needle condition with something that meets your needs.
For single-dimensional arrays you can use array_search(). This can be adapted for multi-dimensional arrays like so:
function array_search_recursive($needle, $haystack, $strict=false, $stack=array()) {
$results = array();
foreach($haystack as $key=>$value) {
if(($strict && $needle === $value) || (!$strict && $needle == $value)) {
$results[] = array_merge($stack, array($key));
}
if(is_array($value) && count($value) != 0) {
$results = array_merge($results, array_search_recursive($needle, $value, $strict, array_merge($stack, array($key))));
}
}
return($results);
}
Write a method something like this:
function valInArr($array, $field, $value) {
foreach ($array as $id => $nestedArray) {
if (strpos($value,$nestedArray[$field])) return $id;
//if ($nestedArray[$field] === $value) return $id; // use this line if you want the values to be identical
}
return false;
}
$meetID = 1234;
$x = valInArr($array, "Meet_Name", $meetID);
if ($x) print_r($array[$x]);
This function will evaluate true if the record is found in the array and also enable you to quickly access the specific nested array matching that ID.
I have the following multidimensional $array:
Array
(
[0] => Array
(
[domain] => example.tld
[type] => 2
)
[1] => Array
(
[domain] => other.tld
[type] => 2
)
[2] => Array
(
[domain] => blaah.tld
[type] => 2
)
)
I simply want to recursively search all the arrays on both key and value, and return true if the key/value was found or false if nothing was found.
Expected output:
search_multi_array($array, 'domain', 'other.tld'); // Will return true
search_multi_array($array, 'type', 'other.tld'); // Will return false
search_multi_array($array, 'domain', 'google.com'); // Will return false
I've figured out a ugly-ugly method to search against the domain against all keys with this function:
function search_multi_array($search_value, $the_array) {
if (is_array($the_array)) {
foreach ($the_array as $key => $value) {
$result = search_multi_array($search_value, $value);
if (is_array($result)) {
return true;
} elseif ($result == true) {
$return[] = $key;
return $return;
}
}
return false;
} else {
if ($search_value == $the_array) {
return true;
}
else
return false;
}
}
Can anyone do better and match both against the key and value in a more elegant way?
If it doesn't go beyond those 2 levels, flipping keys/merging makes life a lot more pleasant:
<?php
$data = array
(
'0' => array
(
'domain' => 'example.tld',
'type' => 2
),
'1' => array
(
'domain' => 'other.tld',
'type' => 2,
),
'2' => array
(
'domain' => 'blaah.tld',
'type' => 2
)
);
$altered = call_user_func_array('array_merge_recursive',$data);
var_dump($altered);
var_dump(in_array('other.tld',$altered['domain']));
var_dump(in_array('other.tld',$altered['type']));
var_dump(in_array('google.com',$altered['domain']));
To go beyond 2nd level, we have to loop once through all the nodes:
$option2 = array();
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($data)) as $key => $value){
$option2[$key][] = $value;
}
var_dump($option2);
One way is to create a reverse mapping from [domain] => [indices] and from [type] => [indices]. It's probably not going to save you much unless you do lots of searches.
(hint: you probably want to wrap it into a class to prevent inconsistencies in the mappings)
also, anytime you see something like this:
if ($search_value == $the_array) {
return true;
} else {
return false;
}
you can always turn it into:
return $search_value == $the_array;
function search_mutli_array($SearchKey, $SearchValue, $Haystack)
{
$Result = false;
if (is_array($Haystack))
{
foreach ($Haystack as $Key => $Value)
{
if (is_array($Value))
{
if (search_mutli_array($SearchKey, $SearchValue, $Value))
{
$Result = true;
break;
}
}
else if ($SearchKey == $Key && $SearchValue == $Value)
{
$Result = true;
break;
}
}
}
return $Result;
}
I am using below code to find an array inside parent array but it is not working that is retuning empty even though the specified key exits in the parent array
$cards_parent = $feedData['BetradarLivescoreData']['Sport']['Category']['Tournament']['Match'];
$cards = array();
foreach($cards_parent as $key => $card)
{
if ($key === 'Cards')
{
$cards[] = $cards_parent[$key];
break;
}
}
Do you know any array function that will search parent array for specified key and if found it will create an array starting from that key?
you want array_key_exists()
takes in a needle (string), then haystack (array) and returns true or false.
in one of the comments, there is a recursive solution that looks like it might be more like what you want. http://us2.php.net/manual/en/function.array-key-exists.php#94601
here you can use recursion:
function Recursor($arr)
{
if(is_array($arr))
{
foreach($arr as $k=>$v)
{
if($k == 'Cards')
{
$_GLOBAL['cards'][] = $card;
} else {
Recursor($arr[$k]);
}
}
}
}
$cards_parent = $feedData['BetradarLivescoreData']['Sport']['Category']['Tournament']['Match'];
$_GLOBAL['cards'] = array();
Recursor($cards_parent);
Could you please put a print_r($feedData) up? I ran the below code
<?php
$feedData = array('BetradarLivescoreData' => array('Sport' => array('Category' => array('Tournament' => array('Match' => array('Cards' => array('hellow','jwalk')))))));
$cards_parent = $feedData['BetradarLivescoreData']['Sport']['Category']['Tournament']['Match'];
$cards = array();
foreach($cards_parent as $key => $card)
{
if ($key === 'Cards')
{
$cards[] = $card;
break;
}
}
print_r($cards);
And it returned a populated array:
Array ( [0] => Array ( [0] => hellow [1] => jwalk ) )
So your code is correct, it may be that your array $feedData is not.