Merging 2 arrays based on a relational array - php

I have the following arrays:
$excel_arr = array(
["C1", "Title 3"],
["A1", "Title 1"],
["B1", "Title 2"],
["D1", "Title 4"]
);
$db_result = array(
"title_2" => "Cell 2 Value",
"title_1" => "Cell 1 Value",
"title_3" => "Cell 3 Value",
"title_5" => "Cell 5 Value"
);
$excel_db_relation = array(
"title_1" => "Title 1",
"title_2" => "Title 2",
"title_3" => "Title 3",
"title_4" => "Title 4",
"title_5" => "Title 5"
);
usort($excel_arr, function ($a, $b) { return strnatcmp($a[0], $b[0]); });
$excel_arr is an array with the titles for each column in an excel file. The first cell defines the cell coordinate and the second the actual cell value.
$db_result is an array containing queried values from a database. The key is column name in the table.
$excel_db_relation is an array which defines the relation between the 2 former arrays. Which excel column is linked to which db table column. In this example they are very similar, but in practice there might be more than just an underscore that differs.
The cell coordinates in $excel_arr defines the order in which each value must be printed. To do this I sort the array with the usort() as seen above.
I need to somehow merge these arrays so that the resulting array becomes:
array("Title 1" => "Cell 1 Value", "Title 2" => "Cell 2 Value", "Title 3" => "Cell 3 Value")
The database array didn't return a value for cell 4 and the excel sheet doesn't define a E5 cell. So these must not be included in the resulting array.
I have tried array_merge($excel_db_relation, $db_result) and various combinations of array_merge() and array_flip() but no matter what I do I can't seem to merge the arrays with "Title X" being the key.

The solution using array_intersect_key, array_intersect and array_column functions:
$result = [];
// getting concurrent 'titles'(by key)
$titles = array_intersect_key($excel_db_relation, $db_result);
foreach (array_intersect($titles, array_column($excel_arr, 1)) as $k => $v) {
$result[$v] = $db_result[$k];
}
print_r($result);
The output:
Array
(
[Title 1] => Cell 1 Value
[Title 2] => Cell 2 Value
[Title 3] => Cell 3 Value
)
Update:
Alternative approach to hold the order in which each value must be printed. Used functions: array_merge_recursive(to combine cell titles and values into separate groups) and array_column functions:
$result = [];
$bindings = array_column(array_merge_recursive($db_result, $excel_db_relation), 0, 1);
foreach (array_column($excel_arr, 1) as $title) {
if (isset($bindings[$title])) $result[$title] = $bindings[$title];
}
print_r($result);
The output:
Array
(
[Title 3] => Cell 3 Value
[Title 1] => Cell 1 Value
[Title 2] => Cell 2 Value
)

Try this:
$result = array_flip($excel_db_relation);
array_walk($result, function(&$value, $key) use ($db_result) {
$value = $db_result[$value];
});
var_dump($result);
But make sure that all keys exist beforehand.

This worked for me:
<?php
//...
usort($excel_arr, function ($a, $b) { return strnatcmp($a[0], $b[0]); });
$result = [];
// traverse the *title* column in the sorted $excel_arr
foreach (array_column($excel_arr, 1) as $a) {
// could use array_flip to speed up this test, though
// this can be problematic if the values aren't *good* array keys
$k = array_search($a, $excel_db_relation);
// if there is a key and it also exists in $db_result
if (false !== $k && array_key_exists($k, $db_result)) {
// assign it to the final result
$result[$a] = $db_result[$k];
}
}
print_r($result);

Related

Regex Preg_match Pattern for Numbers In Array PHP

I have an array of numbers that I need to search through a multidimensional array for.
I have a thousand records of songs. Each song has an array of float values that I need to search through, and I'll need to retrieve the songs if the first digits of each float value match any float number in my array.
So for example my array of numbers I need to find are:
array(14, 18.12, 12.1290, 55.01)
and the songs are sorted in a json file like so:
{"id": 129112, "name": "XYZ Song", "values": { 14.1290, 55.0192, 129 } }
Currently my for loops are taking too long to loop through all the records.
I think I need to sort through the values with a preg_match function and the right pattern (except I'm terrible with regex), what do you guys think?
Please check this code. This code may help you
<?php
// PHP program to carry out multidimensional array search
// Function to recursively search for a given value
function multi_array_search($search_value, $array, $id_path) {
if(is_array($array) && count($array) > 0) {
foreach($array as $key => $value) {
$temp_path = $id_path;
// Adding current key to search path
$temp_path[] = $value;
// Check if this value is an array
// with atleast one element
if(is_array($value) && count($value) > 0) {
$res_path = multi_array_search(
$search_value, $value, $temp_path);
}
else if($value == $search_value) {
print_r($temp_path);
}
}
}
}
// Multidimensional (Three dimensional) array as suggested by you
$songs_array= array(
0 => array(
"id" => "129112",
"name" => "X Song",
"value" => array( 14.1290, 329, 129 )
),
1 => array(
"id" => "129113",
"name" => "XY Song",
"value" => array( 14.1291, 55.0192, 229 )
),
2 => array(
"ic" => "129114",
"name" => "XYZ Song",
"value" => array( 14.1292, 55.0193, 388 )
)
);
$songs= multi_array_search('329', $songs_array, array());
?>
Here I have searched for 329 in $song_array and
Result is :

How to merge a flat array and a multidim array based on indexes and sum subarray column values?

There are two arrays:
$arr1 = [
"Value1",
"Value2",
"Value1"
];
$arr2 = [
["key_1" => "5", "key_2" => "10"], // relates to Value1
["key_1" => "2", "key_2" => "4"], // relates to Value2
["key_1" => "50", "key_2" => "100"] // relates to Value1
];
I cannot simply combine the two arrays because the duplicated values in $arr1 will lead to overwritten data from $arr2.
The behavior that I need is for subarray data to be added if a value from $arr1 is encountered more than once.
I tried to find all sorts of folding options while searching the web, but I could find anything that was right.
I need this output from the sample input arrays:
array (
'Value1' =>
array (
'key_1' => 55,
'key_2' => 110,
),
'Value2' =>
array (
'key_1' => '2',
'key_2' => '4',
),
)
I've tried to write a solution, but I'm not really sure how to tackle the problem.
foreach ($items as $item) {
if (isset($bal[$item['bonus_name']])) {
//Here I don't know how to sum a new one to the repetition?
} else {
$bal[$item['bonus_name']] = $item['bonus_count'];
}
}
Whatever I try, there's no way to sum a repetitive array of elements. I need some help.
Loop the first array to declare the index -> group relationship.
Check if the currently encountered group is unique to the output array. If so, push the entire subarray from the corresponding index in the second array into the output array as the initial values of the group.
If the group is encountered more than once, add each column value to the related amount in the group's subarray.
Code: (Demo)
$result = [];
foreach ($arr1 as $index => $group) {
if (!isset($result[$group])) {
$result[$group] = $arr2[$index];
} else {
foreach ($arr2[$index] as $key => $value) {
$result[$group][$key] += $value;
}
}
}
var_export($result);

sort json results in foreach loop

I am running a foreach loop to display json results, when certain conditions are met, and would like to sort them by the name field. I am trying usort(), but can't seem to figure it out.
JSON:
{
"Shawn Taylor":{
"name":"Shawn Taylor",
"title":"",
"photo_url":"house_165 (1).jpg",
},
"Another Name": {
"name":"Another Name",
"title":"Title is here",
"photo_url":"Person.jpg",
}
}
PHP:
$data_json = file_get_contents('data.json');
$data_array = json_decode($data_json, true);
$i = 0;
foreach($data_array as $key => $person){
if($person['title'] == 'some title'){
include('card.php');
if(++$i % 4 === 0) {
echo '<div class="clearfix"></div>'; // inserts a clearfix every 4 cards
}
}
}
So this returns the all the results I expect, but not sorted. I've tried usort() a few different ways, but just fell on my face terribly:) Please help!
use json_decode first to convert to php array, set the flag to TRUE for associative array $myarr = json_decode($array, TRUE)
the try custom usort
// Sort the multidimensional array
usort($myarr, "custom_sort");
// Define the custom sort function
function custom_sort($a,$b) {
return $a['name']>$b['name'];
}
I hope this helps.
Your json is improperly formatted. There's a couple extra commas, one after each JPG item. Removed below.
Then, json_decode the json string to a PHP associative array, and, since you're using the names as json indexes, ksort (key sort) the resulting array.
$json_string = '{
"Shawn Taylor":{
"name":"Shawn Taylor",
"title":"",
"photo_url":"house_165 (1).jpg"
},
"Another Name": {
"name":"Another Name",
"title":"Title is here",
"photo_url":"Person.jpg"
}
}';
$data_array = json_decode($json_string, true);
ksort($data_array);
// the remaining code
A print_r after the ksort displays:
Array
(
[Another Name] => Array
(
[name] => Another Name
[title] => Title is here
[photo_url] => Person.jpg
)
[Shawn Taylor] => Array
(
[name] => Shawn Taylor
[title] =>
[photo_url] => house_165 (1).jpg
)
)
If you need to sort by a nested index, and you want to maintain the associative array, use uasort:
uasort($data_array, 'sort_name_index');
function sort_name_index($a, $b) {
return $a['name'] > $b['name'];
}

Associative array: Dynamically adding values creates duplicate keys

I declare an array like this:
$statement_row = array(
"Key 1" => "",
"Key 2" => "",
"Key 3" => "");
Then I read data from one table that have corresponding keys in column 0 and value in column 3 so I loop over each row in that table like this:
foreach($table_row as $value){
if(!empty($value[0])){
$statement_row[ $value[0] ] = $value[3];
}
}
This gives an array with duplicate keys of key 1, key 2 and key 3, like this:
array("Key 1" => "","Key 2" => "","Key 3" => "","Key 1" => "Holds value","Key 2" => "Holds value","Key 3" => "Holds value");
Why does it behave like this? Is $value[0] not threated the same way as the defined keys?

PHP: create an array from values in two arrays based on matching keys

The Problem
I would like to create a new associative array with respective values from two arrays where the keys from each array match.
For example:
// first (data) array:
["key1" => "value 1", "key2" => "value 2", "key3" => "value 3"];
// second (map) array:
["key1" => "map1", "key3" => "map3"];
// resulting (combined) array:
["map1" => "value 1", "map3" => "value 3"];
What I've Tried
$combined = array();
foreach ($data as $key => $value) {
if (array_key_exists($key, $map)) {
$combined[$map[$key]] = $value;
}
}
The Question
Is there a way to do this using native PHP functions? Ideally one that is not more convoluted than the code above...
This question is similar to Combining arrays based on keys from another array. But not exact.
It's also not as simple as using array_merge() and/or array_combine(). Note the arrays are not necessarily equally in length.
You can use array_intersect_key() (http://ca2.php.net/manual/en/function.array-intersect-key.php).
Something like that:
$int = array_intersect_key($map, $data);
$combined = array_combine(array_values($map), array_values($int));
Also it would be a good idea ksort() both $map and $data.

Categories