When using array_combine I'm able to combine two array and use the loop through. In the example below I can us $title in my HTML.
{foreach array_combine($p_titles, $p_prices) as $title => $price}<!--SOME HTML-->{/foreach}
However if I try to add another array to this solution it breaks. My local host isn't displaying an error other than "Page not Working "localhost is currently unable to handle this request."
{foreach array_combine($p_titles, $p_prices, $p_ids) as $title => $price => $id}<!--SOME HTML-->{/foreach}
How do I combine 3 or more arrays using this method.
First of all, you tagged Javascript however what you have shown in you question is PHP.
Second, the array_combine only accepts two parameters. Documentation.
To use array_combine for three arrays do this:
$combinedArray = array_combine($p_titles, $p_prices);
$combinedArray = array_combine($combinedArray, $p_ids);
Edit: Answer that matches your code in normal PHP syntax.
$result = array();
foreach($p_titles as $key => $value)
{
$result[$value] = array('price' => $p_prices[$key], 'id' => $p_ids[$key]);
}
echo($result);
You can access this data like these: $result['title']['price'] or $result['title']['id'];
Edit 2: And the Smarty code.
I'm not that familiar with Smarty syntax so this might not work:
{ $result = array(); }
{ foreach from=$p_titles key=key item=value }
{ $result[$value] = array('price' => $p_prices[$key], 'id' => $p_ids[$key]) }
{ /foreach }
Related
I need to get values of array through a loop with dynamic vars.
I can't understand why the "echo" doesn’t display any result for "$TAB['b']".
Do you know why ?
The test with error message : https://3v4l.org/Fp3GT
$TAB_a = "aaaaa";
$TAB['b'] = "bbbbb";
$TAB['b']['c'] = "ccccc";
$TAB_paths = ["_a", "['b']", "['b']['c']"];
foreach ($TAB_paths as $key => $value) {
echo "\n\n\${'TAB'.$value} : "; print_r(${'TAB'.$value});
}
You are treating the array access characters as if they are part of the variable name. They are not.
So if you have an array $TAB = array('b' => 'something');, the variable name is $TAB. When you do ${'TAB'.$value}, you're looking for a variable that's actually named $TAB['b'], which you don't have.
Since you say that you just want to be able to access array indexes dynamically based on the values in another array, you just put the indexes alone (without the array access characters) in the other array.
$TAB['b'] = 'bbbbbb';
$TAB['c'] = 'cccccc';
$TAB_paths = array('b', 'c');
foreach ($TAB_paths as $key => $value) {
echo "\n\n".'$TAB['."'$value'".'] : ' . $TAB[$value];
}
Output:
$TAB['b'] : bbbbbb
$TAB['c'] : cccccc
DEMO
It's unclear what you're trying to do, although you need to include $TAB_all in $TAB_paths:
$TAB_paths = [$TAB_all['a'], $TAB_all['aside']['nav']];
Result:
${TAB_all.aaaaa} : ${TAB_all.bbbbb} :
Not certain what you're needing. My guess you need to merge two arrays into one. Easiest solution is to use the array_merge function.
$TAB_paths = array_merge($TAB_a1, $TAB_a2);
You can define the variable first
foreach ($TAB_all as $key => $value) {
${"TAB_all" . $key} = $value;
}
Now Explore the result:
foreach ($TAB_all as $key => $value) {
print_r(${"TAB_all" . $key});
}
I need to merge/join multiple json string that contains arrays (which also need to be merged) but I don't know what is the best way to achieve this :
Initial array of json strings (called $rrDatas in my example below):
Array
(
[0] => {"asset":[1],"person":[1]}
[1] => {"asset":[2]}
)
Expected result :
{"asset":[1,2],"person":[1]}
The main difficulty is that the number of arrays is undefined (my example is made with 2 arrays but it could be 3,4 etc.). The second difficulty is that there can be multiple properties (like "asset", "person" etc. however always arrays). These possible properties are known but are many so it would be better if the algorithm is dynamic.
What I am able to do at the moment :
$mergedAssets['asset'] = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
$mergedAssets['asset'] = array_merge($mergedAssets['asset'],$rrDataJson['asset']);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);
Result :
{"asset":[1,2]}
This works well but this is not dynamic, should I duplicate this part for each possible properties (i.e. "person", etc.) ?
Thanks,
Guillaume
Edit : Brett Gregson's and krylov123's answers below helped me build my own solution which is a mix between both suggestion:
$mergedJson = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
foreach(array_keys($rrDataJson) as $property)
{
$mergedJson[$property] = array_merge($mergedJson[$property] ?? [], $rrDataJson[$property]);
}
}
return \GuzzleHttp\json_encode($mergedJson, true);
Find below a better example :
$rrDatas = Array (
[0] => {"asset":[1,2],"person":[1],"passive":[1]}
[1] => {"asset":[3],"charge":[1],"passive":[2]}
)
Which must result in :
{"asset":[1,2,3],"person":[1],"passive":[1,2],"charge":[1]}
Edit 2 : I have just tried Progrock's solution and it seems to work perfectly as well : https://3v4l.org/7hSqi
You can use something like:
$output = []; // Prepare empty output
foreach($rrDatas as $inner){
foreach($inner as $key => $value){
$output[$key][] = $value;
}
}
echo json_encode($output); // {"asset":[1,2],"person":[1]}
Which should give you the desired output. This should work regardless of the keys within the individual arrays and even with empty arrays.
Working example here
Another example with more arrays and more keys and empty arrays
<?php
$array =
[
'{"asset":[1],"person":[1]}',
'{"asset":[2]}',
];
$array = array_map(function($v) { return json_decode($v, true);}, $array);
$merged = array_merge_recursive(...$array);
print json_encode($merged);
Output:
{"asset":[1,2],"person":[1]}
You need to use foreach ($array as $key => $value) iteration, to be able to dynamicaly use keys of your json array (e.g. "asset" and "person").
Solution:
$mergedAssets['asset'] = [];
foreach ($rrDatas as $key => $value)
{
$rrDataJson = \GuzzleHttp\json_decode($value, true);
$mergedAssets[$key] = array_merge($mergedAssets[$key],$rrDataJson[$key]);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);
This question already has answers here:
How to search by key=>value in a multidimensional array in PHP
(17 answers)
Closed 9 years ago.
What would be the most efficient way of looking at an array of associative arrays, to find the node which meets a parameter?
I would like to have a more efficient way of looking through the array to find and return the parent node, that just looping through - looking at each element and returning if matched. (it is also safe to assume, that there are no duplicates of data - so the first found, is the only one found)
Or is a for loop the best thing ive got?
e.g.
array(
[0] => array('name' => 'fred'),
[1] => array('name' => 'dave'),
[2] => array('name' => 'mike)
)
And wanting to get the node of data where the name == 'dave' or to see if there is in fact a node which has a element name set as 'dave'.
e.g. somthing like
isset($data[]['name'] == 'dave')
$info = getdata($data[]['name'] == 'dave')
(Apologies if I'm not using the correct technical terms, please do correct me as I do like to learn!)
Many thanks in advance for any advice! =)
There is no better way than looping. PHP can't perform any magic that does not involve looking at each element in turn.
If you're doing this often, it helps to index your arrays by the search criterion:
$data = array(
array('name' => 'Dave'),
array('name' => ...)
);
$indexedData = array();
foreach ($data as $datum) {
$indexedData[$datum['name']] = $datum;
}
$info = $indexedData['Dave'];
As long as your data structure is sub-optimal, there's only sub-optimal ways to access it.
Here's a function for array recursion to one level. We use foreach() to loop through each second layer of child arrays, then use the built-in function array_search to see if it exists.
function as_nested($needle,$haystack){
$val;
foreach($haystack as $key=>$arr){
$arr_key = array_search($needle,$haystack[$key]);
if(!empty($arr_key)){
$val = $key;
}
}
return $val;
}
To execute, you supply the needle, then the haystack.
echo as_nested('dave',$myArray);
Output using your initial array is 1.
$myArray[0] = array('name'=>'fred');
$myArray[1] = array('name' => 'dave');
$myArray[2] = array('name' => 'mike');
There is a function in php called in_array() that looks for a value in an array.
//Code credit to #deceze
$data = array(
array('name' => 'Dave'),
array('name' => ...)
);
function getData($data, $searchValue) {
foreach ($data as $datum) {
if (in_array($searchValue, $datum)) {
return $datum;
}
}
//array returned when $searchValue is found.
You can use the getData function to search for a value in an array (this is not index specific. ie not restricted by only name, etc.)
I am building a web crawler. It finds all the links on a page and their titles and meta descriptions etc. It does that fine. Then i wrote an array which gives all the starting urls for the links I want. So if it crawls a link and its url begins with any value in the array which gives the starting urls, insert into $news_stories.
The only problem is it doesn't seem to be inserting into them. The page returns blank and now it says that the array_intersect statement wants an array and that I havent specfied an array which I have.
In summary, I am struggling to understand where my code doesn't work and why the wanted urls aren't being inserted.
$bbc_values = array(
'http://www.bbc.co.uk/news/health-',
'http://www.bbc.co.uk/news/politics-',
'http://www.bbc.co.uk/news/uk-',
'http://www.bbc.co.uk/news/technology-',
'http://www.bbc.co.uk/news/england-',
'http://www.bbc.co.uk/news/northern_ireland-',
'http://www.bbc.co.uk/news/scotland-',
'http://www.bbc.co.uk/news/wales-',
'http://www.bbc.co.uk/news/business-',
'http://www.bbc.co.uk/news/education-',
'http://www.bbc.co.uk/news/science_and_enviroment-',
'http://www.bbc.co.uk/news/entertainment_and_arts-',
'http://edition.cnn.com/'
);
// BBC Algorithm
foreach ($links as $link) {
$output = array(
"title" => Titles($link), //dont know what Titles is, variable or string?
"description" => getMetas($link),
"keywords" => getKeywords($link),
"link" => $link
);
if (empty($output["description"])) {
$output["description"] = getWord($link);
}
}
$new_stories = array();
foreach ($output as $new_array) {
if (array_intersect($output['link'], $bbc_values) == true) {
$news_stories[] = $new_array;
}
print_r($news_stories);
}
You decalred the array as $new_stories and printing $news_stories..... diff is 'S'
check whether the code is coming inside this loop or not, i think not...
if (array_intersect($output['link'], $bbc_values) == true) {
echo 'here';
}
Hmm i don't think array_intersect is what you need for a comparison http://php.net/manual/en/function.array-intersect.php
Maybe you want to look for in_array http://php.net/manual/en/function.in-array.php
When the return parameter is used, this function uses internal output buffering so it cannot be used inside an ob_start() callback function.
$mainMenu['Home'][1] = '/mult/index.php';
$mainMenu['Map'][1] = '/mult/kar.php';
$mainMenu['MapA'][2] = '/mult/kara.php';
$mainMenu['MapB'][2] = '/mult/karb.php';
$mainMenu['Contact'][1] = '/mult/sni.php';
$mainMenu['Bla'][1] = '/mult/vid.php';
This is a menu, 1 indicates the main part, 2 indicates the sub-menu. Like:
Home
Map
-MapA
-MapB
Contat
Bla
I know how to use foreach but as far as I see it is used in 1 dimensional arrays. What I have to do in the example above?
You would need to nest two foreach BUT, there is nothing about your data structure that easily indicates what is a sub-item. Map vs. MapA? I guess a human could figure that out, but you'll have to write a lot of boilerlate for your script to sort that.. Consider restructuring your data so that it more closely matches what you are trying to achieve.
Here's an example. You can probably come up with a better system, though:
$mainMenu = array(
'Home' => '/mult/index.php',
'Map' => array(
'/mult/kar.php',
array(
'MapA' => '/mult/kara.php',
'MapB' => '/mult/karb.php'
)
),
'Contact' => '/mult/sni.php',
...
);
You nest foreach statements; Something like this should do the work.
foreach($mainMenu as $key=>$val){
foreach($val as $k=>$v){
if($k == 2){
echo '-' . $key;
}else{
echo $key;
}
}
}
Foreach can just as easily be used in multi-dimensional arrays, the same way you would use a for loop.
Regardless, your approach is a little off, here's a better (but still not great) solution:
$mainMenu['Home'][1] = '/mult/index.php';
$mainMenu['Map'][1] = '/mult/kar.php';
$mainMenu['Map']['children']['MapA'] = '/mult/kara.php';
$mainMenu['Map']['children']['MapB'] = '/mult/karb.php';
$mainMenu['Contact'][1] = '/mult/sni.php';
$mainMenu['Bla'][1] = '/mult/vid.php';
foreach($mainMenu as $k => $v){
// echo menu item
if(isset($v['children'])){
foreach($v['children'] as $kk => $vv){
// echo submenu
}
}
}
That said, this only does 1-level of submenus. Either way, it should help you get the idea!