Basically I have this array:
array(
[0] => array("id" => "0", "header" => "img1"),
[1] => array("id" => "4", "header" => "img4")
[2] => array("id" => "6", "header" => "img6")
)
If I have $id = "4", how can I extract the index [1] to obtain "header" value?
You will want to do a foreach loop for this. But honestly if you structured your array indexes better than you could just to a simple isset test and then grab the value once you verify it is there.
The right way:
$headers = array(0 => 'img1', 4 => 'img4', 6 => 'img6');
if (isset($headers[$index])) {
return $headers[$index];
}
Here is how to deal with it with your array (much more costly from a processing standpoint):
$headers = array(
0 => array("id" => "0", "header" => "img1"),
1 => array("id" => "4", "header" => "img4"),
2 => array("id" => "6", "header" => "img6")
);
foreach ($headers AS $value) {
if ($value['id'] == $index) {
return $value['header'];
}
}
foreach ($array as $key => $value) {
if ($value['id'] == '4') {
echo $value['header'];
break;
}
}
It will be better to store id and header like this for example:
array(
"0" => "img1",
"4" => "img4",
"6" => "img6",
);
Arrays in PHP are actually hash tables behind the scenes, so accessing elements by key is extremely fast. If you can, change the way your array is created at the source to use the id (which I assume is unique) as the key, as already mentioned in other answers.
To transform your current array to be indexed by id, you could use this code:
$indexed = array();
foreach($array as $element) {
$indexed[$element['id']] = $element['header'];
}
// $indexed now resembles id => header
You can then access header values in constant time using $indexed[$id].
Related
you will see maybe this problem sounds silly but it has tended me a bit stuck.
You see, I have a function which receives an array, with this array a sum must be made, specifically sum one of its columns (I enter as the third parameter of the function the column I want to sum).This work good. The problem is the way it generates the result. I show you my code:
function sumArray($array, $index, $col) {
$returnArray = []; // temporary container
// sanity checks
if (!is_array($array)) {
return 'error not an array';
}
$firstRow = reset($array);
if (!array_key_exists($index, $firstRow) || !array_key_exists($col, $firstRow)) {
return 'error keys provided not found';
}
foreach ($array as $value) {
if (!isset($returnArray[$value[$index]])) { // initialize
$returnArray[$value[$index]] = [$index => $value[$index], $col => 0];
}
// add value
$returnArray[$value[$index]][$col] += $value[$col]; //here is the sum
}
return $returnArray;
}
$products = array ( //this is the array
array("Id" => "000001",
"Name" => "Cheese",
"Quantity" => "0.00000012",
"Price" => "10"),
array("Id" => "000001",
"Name" => "Cheese",
"Quantity" => "0.00000123",
"Price" => "20"),
array("Id" => "000001",
"Name" => "Cheese",
"Quantity" => "0.00000020",
"Price" => "30"),
array("Id" => "000002",
"Name" => "Ham",
"Quantity" => "0.00000346",
"Price" => "200"),
array("Id" => "000002",
"Name" => "Ham",
"Quantity" => "0.000000998",
"Price" => "100"),
array("Id" => "000003",
"Name" => "Baicon",
"Quantity" => "0.000000492",
"Price" => "900")
);
$summedArray = sumArray($products, 'Name', 'Quantity');
print_r($summedArray);
the result of my sum is a new array. But look at the Quantity column:
Array (
[Cheese] => Array ( [Name] => Cheese [Quantity] => 1.55E-6 )
[Ham] => Array ( [Name] => Ham [Quantity] => 4.458E-6 )
[Baicon] => Array ( [Name] => Baicon [Quantity] => 4.92E-7 )
)
This form: 4.458E-6 I don't like. I would like something like this: 0.000004458
Do you know what I could do to get something like that? A suggestion would be of great help.
It isn't really related to the fact that it's a sum. That's just the default string representation of a small float in PHP. Try this, for example:
$number = 0.000004458;
echo $number; // displays 4.458E-6
The only reason the appearance changes in your output is that those values are strings in your input array, but when you add them together they are converted to floats.
If you want those values to display differently, you'll need to use some kind of formatting function that returns a string.
Assuming you aren't going to be using print_r to display the value in your final product, you can use number_format or printf to display it with however many decimal points you'd like.
foreach ($summedArray as $product => $info) {
echo number_format($info['Quantity'], 9) . PHP_EOL;
// or printf('%.9f', $info['Quantity']) . PHP_EOL;
}
I have array inside array:
{
"0" => array("key" => "code", "id" => "4", "value" => "yes"),
"1" => array("key" => "parameter", "id" => "4", "value" => "0"),
"2" => array("key" => "code", "id" => "5", "value" => "no"),
etc...
}
This is what I want to do: I want to have one dimension array in which key would be "id" and value would be "value". However, I need to filter out entries whose key is "parameters". So, in this example, the final array should look like this:
{
"4" => "yes",
"5" => "no"
}
I just can't seem to figure out how to do this. Could you please help me a bit? I tried writing this foreach inside foreach but I just can't wrap my head around how to filter data.
foreach ($settings AS $key => $value) {
$id = null;
$value = null;
foreach ($value AS $key2 => $value2) {
// No idea how to filter out uneccesary entries and save the correct ones
}
$finalArray[$id] = $value;
}
This should do it :
$finalArray = array();
foreach ($settings as $setting) {
if ($setting['key'] != 'parameter') {
$finalArray[$setting['id']] = $setting['value'];
}
}
Assuming all your entries have keys 'key', 'id' and 'value'.
use array_column and array_filter like this, if you want to filter more keys add them to out_keys array :
<?php
$array = [
["key" => "code", "id" => "4", "value" => "yes"],
["key" => "parameter", "id" => "4", "value" => "0"],
["key" => "code", "id" => "5", "value" => "no"]
];
$out_keys = ['parameter'];
$result = array_column(array_filter($array, function($item) use($out_keys) {
return !in_array($item['key'], $out_keys);
}), 'value', 'id');
echo "<pre>";
print_r($result);
output:
Array
(
[4] => yes
[5] => no
)
Assuming $data is your starting array, the code below will output what you want in $result
$result = [];
foreach(array_filter($data, function($el){return $el['key']!='parameter';}) as $el){
$result[$el['id']] = $el['value'];
}
Live demo
I have two multidimensional dynamic arrays like so in PHP:
$old = array(
"meta_data" => array(
"page_title" => "Test1",
"page_description" => "Test2",
"page_keywords" => "Test3"
),
"content" => array(
"page_header_one" => "1",
"page_content_one" => "2",
"page_header_two" => "3",
"page_content_two" => "4",
"page_header_three" => "5"
),
);
$new = array(
"meta_data" => array(
"page_title" => "Test1",
"page_description" => "Test2",
"page_keywords" => "Test3324"
),
"content" => array(
"page_header_one" => "124",
"page_content_one" => "243",
"page_header_two" => "343"
),
);
I'm struggling to compare these as they're dynamic, e.g. the keys change. What I'm aiming to do is compare the arrays, find out what's changed, leave out keys that don't match, and only add the changes to the new array.
The only things that will be constant are "meta_data" and "content"
So for example in $old we have 5 items in the content array, but in the $new array we only have 3 items (3 changed items), so the new array would have 3 content items.
Is there a way to do this I can't for the life in me figure out how?
Final array should look like so:
$final = array(
"meta_data" => array(
"page_keywords" => "Test3324"
),
"content" => array(
"page_header_one" => "124",
"page_content_one" => "243",
"page_header_two" => "343"
),
);
Maybe it can be done easier, but I think this will do the job:
<?php
$newArray = [];
foreach($old['meta_data'] as $key => $value) {
if(array_key_exists($key, $new['meta_data'])) {
if($new['meta_data'][$key] == $old['meta_data'][$key]) {
$newArray['meta_data'][$key] = $value;
}
}
}
foreach($old['content'] as $key => $value) {
if(array_key_exists($key, $new['content'])) {
if($new['content'][$key] == $old['content'][$key]) {
$newArray['content'][$key] = $value;
}
}
}
You can also make the top key dynamic, so content and meta_data are dynamic as well, like this:
foreach($old as $topKey => $subArray) {
if(array_key_exists($topKey, $new)) {
foreach($subArray as $key => $value) {
if(array_key_exists($key, $new[$topKey])) {
if($new[$topKey][$key] == $old[$topKey][$key]) {
$newArray[$topKey][$key] = $value;
}
}
}
}
}
I haven't tested it. But I think you'll get the gist.
The only things that will be constant are "meta_data" and "content"
Given this thing in mind, the solution to your problem would be to use array_diff() function like this:
$final = array();
$final['meta_data'] = array_diff($new['meta_data'], $old['meta_data']);
$final['content'] = array_diff($new['content'], $old['content']);
// display $final array
var_dump($final);
Here's a live demo
You can simply use the PHP array_diff() function.
$final = array_diff($new, $old);
I'm trying to manipulate an associative multidimensional array. I've extracted the keys from an array that I want to apply to another's values . . .
These are the keys that I've extracted in another function
$keys = array (
"id" => "id",
"addr_street_num" => "addr_street_num",
"addr_street" => "addr_street",
"price" => "price",
"days" =>"days",
"state" => Array
(
"id" => "id",
"name" => "name"
),
"city" => Array
(
"id" => "id",
"web_id" => "web_id",
"name" => "name"
)
);
This array has the values I'd like to combine together
$vals = array (
"0" => "830680",
"1" => "20",
"2" => "Sullivan Avenue",
"3" => "333000",
"4" => "12",
"5" => Array
(
"0" => "4",
"1" => "Maryland",
),
"6" => Array
(
"0" => "782",
"1" => "baltimore",
"2" => "Baltimore",
)
);
When I try to do array_combine($keys, $val);
I get 2 Notices about Array to string conversion
I guess array_combine only works on one dimensional arrays, any ideas on how to approach this?
If $keys was modified could it be combined with the values - problem is the shape of $keys is what I want to end up with?
It can be done recursively.
function combine_recursive($keys, $values) {
$result = array();
$key = reset($keys);
$value = reset($values);
do {
if (is_array($value)) {
$result[key($keys)] = combine_recursive($key, $value);
} else {
$result[key($keys)] = $value;
}
$value = next($values);
} while ($key = next($keys));
return $result;
}
This works for me with your example arrays. I'm sure this will give you all kinds of weird results/errors if the array structures are different from each other at all.
I have this array:
array(
"tour_0" => 1446,
"tour_1" => 1471,
"date-from-1471" => "2014-08-07",
"date-to-1471" => "2014-08-15",
"tour_2" => 30,
"date-from-30" => 2014-08-01,
"date-to-30" => 2014-08-05,
"tour_3" => 10
)
Now, i need it to be sorted to this:
array(
"0" => array("ID" => 1446),
"1" => array("ID" => 1471, "from" => "2014-08-07", "to" => "2014-08-15"),
"2" => array("ID" => 30, "from" => "2014-08-07", "to" => "2014-08-15"),
"3" => array("ID" => 10),
)
How can i accomplish this thing?
I've tried all sorts of things but i can't seem to figure this one out...
Thank's and sorry about the title but i just don't know how to describe it.
How about this?
$ret = [];
foreach($inputArray as $key => $value) {
if (preg_match('/^tour_([0-9]+)/', $key)) {
$ret[$value] = ["ID" => $value];
}
if (preg_match('/date-from-([0-9]+)/', $key, $matches)) {
$ret[$matches[1]]["from"] = $value;
}
if (preg_match('/date-to-([0-9]+)/', $key, $matches)) {
$ret[$matches[1]]["to"] = $value;
}
}
print_r($ret);
/*
Array
(
"1446" => Array ("ID" => 1446),
"1471" => Array ("ID" => 1471, "from" => "2014-08-07", "to" => "2014-08-15"),
"30" => Array ("ID" => 30, "from" => "2014-08-01", "to" => "2014-08-05"),
"10" => Array ("ID" => 10)
)*/
Close enough? (it is quite trival change the keys of the array, considering they are in order (0, 1, 2, 3, ...), if they are not, maybe you can save the order also (in another item of the subarray) and recompose again once this array is formed)