How can I check if the values are unique in an array based on the key value? Below is the out put of the array. I want to remove duplicate values based on the "id" key. If you check below, the 2nd & 3rd array are same except for the "role" value. Because of this, array_unique is not working on this array.
array
0 =>
array
'id' => string '1521422' (length=7)
'name' => string 'David Alvarado' (length=14)
'role' => string 'associate producer ' (length=20)
1 =>
array
'id' => string '0098210' (length=7)
'name' => string 'Cristian Bostanescu' (length=19)
'role' => string 'line producer: Romania (as Cristi Bostanescu)' (length=46)
2 =>
array
'id' => string '1266015' (length=7)
'name' => string 'Bruno Hoefler' (length=13)
'role' => string 'co-producer ' (length=13)
3 =>
array
'id' => string '1266015' (length=7)
'name' => string 'Bruno Hoefler' (length=13)
'role' => string 'executive producer ' (length=20)
4 =>
array
'id' => string '1672379' (length=7)
'name' => string 'Alwyn Kushner' (length=13)
'role' => string 'associate producer ' (length=20)
Try this one:
<?php
$array = array(
array('id' => 1, 'text' => 'a'),
array('id' => 2, 'text' => 'b'),
array('id' => 1, 'text' => 'c'),
array('id' => 3, 'text' => 'd')
);
$array = array_filter($array, function ($item) {
static $found = array();
if (isset($found[$item['id']])) return false;
$found[$item['id']] = true;
return true;
});
var_dump($array);
This works as of PHP 5.3 (because of the closure and static statement).
cf. http://php.net/manual/en/function.array-filter.php for more information. I tested the statement within loops, it works there as well.
Basically you want to implement a variation of array_unique that does what you want:
function array_unique_multi($arr,$key='id') {
// $arr is the array to work on
// $key is the key to make unique by
$ret = Array();
foreach($arr as $v) {
if( !isset($ret[$v[$key]])) $ret[$v[$key]] = $k;
}
return array_values($ret);
}
You can use this code:
// assuming $arr is your original array
$narr = array();
foreach($arr as $key => $value) {
//$narr[json_encode($value)] = $key;
if (!array_key_exists($value["id"], $narr))
$narr[$value["id"]] = $key;
}
$narr = array_flip($narr);
foreach($arr as $key => $value) {
if (!array_key_exists($key, $narr))
unset($arr[$key]);
}
print_r($arr); // will have no duplicates
Related
I have tried a number of PHP functions like array_unique to merge the arrays I have but that does not work since these are not strings.
The starting output would be this on var_dump( $country_cities );
array (size=3)
0 =>
array (size=1)
'BH' =>
array (size=4)
'post_id' => int 7886
'country' => string 'BH' (length=2)
'city_name_eng' => string 'Laurence' (length=8)
'city_name_arabic' => string '3684hdfpfwbhisf' (length=15)
1 =>
array (size=1)
'BH' =>
array (size=4)
'post_id' => int 7885
'country' => string 'BH' (length=2)
'city_name_eng' => string 'Bahrain City' (length=12)
'city_name_arabic' => string 'vgdg824762' (length=10)
2 =>
array (size=2)
'BH' =>
array (size=4)
'post_id' => int 7885
'country' => string 'BH' (length=2)
'city_name_eng' => string 'Bahrain City' (length=12)
'city_name_arabic' => string 'vgdg824762' (length=10)
'KW' =>
array (size=4)
'post_id' => int 7841
'country' => string 'KW' (length=2)
'city_name_eng' => string 'Kuwait City' (length=11)
'city_name_arabic' => string ' مدينة الكويت' (length=24)
The Code below merges the different arrays above.
<?php
// Make the cities unique. Remove duplicates form the inner array.
$uniques = [];
foreach($country_cities as $arr ) {
foreach( $arr as $v) {
if( !in_array($v, $uniques, false) ) {
$uniques[$v['country']] = $v;
}
}
}
var_dump($uniques);
Results logged show the code cuts out some of the arrays.
/Users/..... on line php:74:
array (size=2)
'BH' =>
array (size=4)
'post_id' => int 7885
'country' => string 'BH' (length=2)
'city_name_eng' => string 'Bahrain City' (length=12)
'city_name_arabic' => string 'vgdg824762' (length=10)
'KW' =>
array (size=4)
'post_id' => int 7841
'country' => string 'KW' (length=2)
'city_name_eng' => string 'Kuwait City' (length=11)
'city_name_arabic' => string ' مدينة الكويت' (length=24)
Please help figure out my error or suggest a better way to fix it.
If I understood you correctly, this should be the result you wanted to achieve.
Each country code will be included once, while the cities (based on post_id) will only be added once.
<?php
$result = [];
$processedIds = [];
foreach ($country_cities as $ccs) {
foreach ($ccs as $cc => $details) {
// If the country has not yet been added to
// the result we create an outer array.
if (!key_exists($cc, $result)) {
$result[$cc] = [];
}
$postId = $details['post_id'];
if (!in_array($postId, $processedIds)) {
// Add the unique city to country's collection
$result[$cc][] = $details;
// Keep track of the post_id key.
$processedIds[] = $postId;
}
}
}
print_r($result);
<?php
//...
$uniques = [];
foreach($country_cities as $data ) {
foreach( $data as $countryCode => $item) {
if( !array_key_exists($countryCode, $uniques) ) {
$uniques[$countryCode] = []; //Create an empty array
}
$targetArray = &$uniques[$countryCode];
if( !array_key_exists($item['post_id'], $targetArray) ) {
$targetArray[$item['post_id']] = $item; //Create an empty array
}
}
}
Maybe this code will help?
I'm trying to escape values from a multidimensional array for my database class. The code I have currently:
// Function to escape array values
private function esc_sql_arr(array $to_esc) {
$clean_arr = array();
foreach($to_esc as $k => $v) {
if(is_array($to_esc[$k])) {
foreach($to_esc[$k] as $key => $val) {
$k = $this->_mysqli->real_escape_string($k);
$key = $this->_mysqli->real_escape_string($key);
$val = $this->_mysqli->real_escape_string($val);
$clean_arr[$k][$key] = $val;
}
} else {
$k = $this->_mysqli->real_escape_string($k);
$v = $this->_mysqli->real_escape_string($v);
$clean_arr[$k] = $v;
}
}
return $clean_arr;
}
I'm assuming the following input example (it should be 'where', I purposely changed it to test the above method):
$args = array(
"table" => "t'1",
"data" => array(
"c'sf4;(" => 'xdfbxdrf',
'c2' => "'t'est'",
'cs' => 'hey'
),
"whe're" => array(
'test' => 'test1'
)
);
var_dump:
array (size=3)
'table' => string 't\'1' (length=4)
'data' =>
array (size=3)
'c\'sf4;(' => string 'xdfbxdrf' (length=8)
'c2' => string '\'t\'est\'' (length=10)
'cs' => string 'hey' (length=3)
'whe\'re' =>
array (size=1)
'test' => string 'test1' (length=5)
The code works without any issue. However, is this the right way to escape a multidimensional array?
I believe I might not have to use this method since I use prepared statements. Any feedback on using this is welcome.
I want the array to merge into a key value pair. look at the example below
Here is my code and array $aExtraFilter
array (size=4)
0 =>
array (size=2)
'key' => string 'CookTech' (length=8)
'value' => string 'Broil' (length=5)
1 =>
array (size=2)
'key' => string 'CookTech' (length=8)
'value' => string 'Pan Fry' (length=7)
2 =>
array (size=2)
'key' => string 'CookSkills' (length=10)
'value' => string 'Intro' (length=5)
3 =>
array (size=2)
'key' => string 'CookSkills' (length=10)
'value' => string 'Knife Skills' (length=12)
Here is my code:
$aExtraFilter2 = [];
$extrafilterkey = '';
$extrafiltervalue = [];
foreach ($aExtraFilter as $key => $value) {
$extrafilterkey = $value['key'];
$aExtraFilter2[$extrafilterkey] = [];
array_push($extrafiltervalue, $value['value']);
$aExtraFilter2[$extrafilterkey] = implode(',', $extrafiltervalue);
}
var_dump($aExtraFilter2);
the output is :
array (size=2)
'CookTech' => string 'Broil,Pan Fry' (length=13)
'CookSkills' => string 'Broil,Pan Fry,Intro,Knife Skills' (length=32)
I want it to look like this:
array (size=2)
'CookTech' => string 'Broil,Pan Fry' (length=13)
'CookSkills' => string 'Intro,Knife Skills' (length=32)
I think I'm almost there but I guess I need some help.
This line does nothing because it is superseded just a bit later as the same variable is being set:
$aExtraFilter2[$extrafilterkey] = [];
This line appends to the array regardless of what you have as $value['key'], which is why you get all keys lumped together in the output:
array_push($extrafiltervalue, $value['value']);
This will produce a desired output:
// fill array of arrays
$aExtraFilter2 = [];
foreach ($aExtraFilter as $key => $value) {
if (!array_key_exists($value['key'], $aExtraFilter2)) $aExtraFilter2[$value['key']] = [];
$aExtraFilter2[$value['key']][] = $value['value'];
}
// convert to string (if needed at all, depends on what you're doing later)
foreach ($aExtraFilter2 as $key => $set) {
$aExtraFilter2[$key] = join(',', $set);
}
The typical way to code this is by creating a temporary structure, based on the key and comprising an array with the values:
$tmp = [];
foreach ($aExtraFilter as $pair) {
$tmp[$pair['key']][] = $pair['value'];
}
The structure would look like this afterwards:
[
'CookTech' => ['Broil', 'Pan Fry'],
'CookSkills' => ['Intro', 'Knife Skills'],
]
Then, you map that array against the representation you want to have:
$aExtraFilter2 = array_map(function($values) {
return join(',', $values);
}, $tmp);
See also: array_map()
I have a json file with this below format structure.
[
{
"name":"banana",
"type":"fruit",
"rate":10
},
{
"name":"orange",
"type":"fruit",
"rate":20
},
{
"name":"apple",
"type":"fruit",
"rate":30
}
]
I would like to update the rate of the fruit by +1 when i match a search for it.
1 . Read the json file
$json_file = file_get_contents('fruits.txt');
2 . Decoded the json file
$fruit_list=json_decode($json_file,true);
VarDumping the Decoded json file is like this
array (size=3)
0 =>
array (size=3)
'name' => string 'banana' (length=6)
'type' => string 'fruit' (length=5)
'rate' => int 10
1 =>
array (size=3)
'name' => string 'orange' (length=6)
'type' => string 'fruit' (length=5)
'rate' => int 20
2 =>
array (size=3)
'name' => string 'apple' (length=5)
'type' => string 'fruit' (length=5)
'rate' => int 30
Wrote a search function to search the array for fruit name
function search_by_key_and_value($array, $key, $value)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value)
$results[] = $array;
foreach ($array as $subarray)
$results = array_merge($results, search_by_key_and_value($subarray, $key, $value));
}
return $results;
}
$result = search_by_key_and_value($fruit_list,"name",apple);
when the function is supplied with fruit name the whole of json file is searched and the RESULT_MATCH is printed var_dump($result) is like this below
array (size=1)
0 =>
array (size=3)
'name' => string 'apple' (length=5)
'type' => string 'fruit' (length=5)
'rate' => int 30
How can i find the array index number as the result of array index is 0 in the result but its position in the main file point no 3 is indexed at 2 or at-least how can i update the matched retsult rate directly ?
I feel like I am so close to successfully switching Jim and Jill in this associative array. I ALSO would like it to be repeatable, so if 'Joe' is added to the end, it will also swap 'Jim' and 'Joe.' Any pointers?
<?php
function jim_is_jill($their_name) {
$first = key($their_name);
foreach ($their_name as $key => $value) {
$lastmaybe = $key;
}
$lastmaybe = $these; // Lastmaybe is Jill
$these = $first;
return $their_name;
}
$their_name = array(
// Key => Value
'Jim' => 'dad',
'Josh' => 'son',
'Jamie' => 'mom',
'Jane' => 'daughter',
'Jill' => 'daughter'
);
print_r(jim_is_jill($their_name));
?>
CURRENT OUTPUT:
Array
(
[Jim] => dad
[Josh] => son
[Jamie] => mom
[Jane] => daughter
[Jill] => daughter
)
DESIRED OUTPUT:
Array
(
[Jill] => dad
[Josh] => son
[Jamie] => mom
[Jane] => daughter
[Jim] => daughter
)
Considering the array
$their_name = array(
// Key => Value
'Jim' => 'dad',
'Josh' => 'son',
'Jamie' => 'mom',
'Jane' => 'daughter',
'Jill' => 'daughter'
);
This function will produce :
function array_swap_values($array, $key1, $key2) {
$temp = $array[$key1];
$array[$key1] = $array[$key2];
$array[$key2] = $temp;
return $array;
}
$their_name = array_swap_values($their_name, 'Jim', 'Jill');
// -> array(
// 'Jim' => 'daughter',
// 'Josh' => 'son',
// 'Jamie' => 'mom',
// 'Jane' => 'daughter',
// 'Jill' => 'dad'
// );
Or this function will produce
function array_swap_keys($array, $key1, $key2) {
$ret = array();
foreach ($array as $key => $value) {
if ($key === $key1) {
$ret[$key2] = $array[$key2];
} else if ($key === $key2) {
$ret[$key1] = $array[$key1];
} else {
$ret[$key] = $value;
}
}
return $ret;
}
$their_name = array_swap_keys($their_name, 'Jim', 'Jill');
// -> array(
// 'Jill' => 'daughter',
// 'Josh' => 'son',
// 'Jamie' => 'mom',
// 'Jane' => 'daughter',
// 'Jim' => 'dad'
// );
** Update **
After your last edit, I modified the last function to return what is expected. It is pretty close to the first function, but it preserve the key ordering :
function array_swap_key_value($array, $key1, $key2) {
$ret = array();
foreach ($array as $key => $value) {
if ($key === $key1) {
$ret[$key2] = $array[$key1];
} else if ($key === $key2) {
$ret[$key1] = $array[$key2];
} else {
$ret[$key] = $value;
}
}
return $ret;
}
$their_name = array_swap_key_value($their_name, 'Jim', 'Jill');
// -> array(
// 'Jill' => 'dad',
// 'Josh' => 'son',
// 'Jamie' => 'mom',
// 'Jane' => 'daughter',
// 'Jim' => 'daughter'
// );
First thing, in my experience, it's not wise to rely on the order of an array, if it is not indexed by numbers. There are no tools (correct me if I'm wrong) to switch positions of keys or change keys themselves. It would have to be ugly hack. The only way to rename a key is to remove it and put it back correctly. But that disturbs the order of an array. You'll really have to rebuild the array from scratch, that's an easiest way, as suggested by Yanick, if you really want to do what you want to do. But there's more neat solution. You can make an array with numbered indexes, which you-shall-not-touch. That way, it will stay order. Then put simple small array in each value:
array('name'=> 'Jill, 'relationship'=>'daughter);
That way, you have full control of the order of indexes (thanks to numbered indexes) and you will only have to swap values, which is dead easy.
Or, you can omit those words and give it just numbered indexes everywhere. That way you'll write less but you will have to remember which is which:
array('jill', 'daughter');
is effectively same as:
array(0 => 'Jill', 1 => 'daughter');
So here's the code..
<?php
function swap_first_and_last($their_name) {
//get first and last keys
reset($their_name); // resets the array pointer to beginning
$k_first=key($their_name); // first key
end($their_name);
$k_last=key($their_name); // last key
// swap first and last:
$swap = $their_name[$k_first]['name'];
$their_name[$k_first]['name']=$their_name[$k_last]['name'];
$their_name[$k_last]['name']=$swap;
// note: you can use [0] and [1], if you modify your array that way
return $their_name;
}
// modified array
$their_name = array(
// note, you can omit those 0 => , 1 => ,2,... keys
0 => array('name' => 'Jim', 'relationship' => 'dad'),
1 => array('name' => 'Josh', 'relationship' => 'son'),
2 => array('name' => 'Jamie', 'relationship' => 'mom'),
3 => array('name' => 'Jane', 'relationship' => 'daughter'),
4 => array('name' => 'Jill', 'relationship' => 'daughter')
);
var_dump(swap_first_and_last($their_name));
And the result is:
array (size=5)
0 =>
array (size=2)
'name' => string 'Jill' (length=4)
'relationship' => string 'dad' (length=3)
1 =>
array (size=2)
'name' => string 'Josh' (length=4)
'relationship' => string 'son' (length=3)
2 =>
array (size=2)
'name' => string 'Jamie' (length=5)
'relationship' => string 'mom' (length=3)
3 =>
array (size=2)
'name' => string 'Jane' (length=4)
'relationship' => string 'daughter' (length=8)
4 =>
array (size=2)
'name' => string 'Jim' (length=3)
'relationship' => string 'daughter' (length=8)