I have the following array.
array(
[PM-AAA] => Array
(
[codePm] => PM-32249
[codeArt] => Array
(
[0] => 32249
)
[codeArtInFlux] => Array
(
[0] => 123456
)
)
[PM-BBB] => Array
(
[codePm] => PM-32249
[codeArt] => Array
(
[0] => 33270
)
[codeArtInFlux] => Array
(
[0] => 484946
)
)
[PM-CCC] => Array
(
[codePm] => PM-82242
[codeArt] => Array
(
[0] => 82242
[1] => 82245
[2] => 82246
)
[codeArtInFlux] => Array
(
[0] => 5191
[1] => 51949
[2] => 26486
)
)
)
I want keep the array where the "codePm" value is unique. For exemple, in the above array, the "PM-CCC" array will be keep, because the "codePm" is unique, contrary to the "PM-AAA" and "PM-BBB", which share the same "codePm"'s value.
Is it possible to do it with one function ?
As I know, there isn't any function that do it directly, you can try this:
function insert_unique_key($key_name,$elem,&$array) {
//Get all elements with the key
$values=array()
foreach ($array as $ii) {
$values[]=$ii[$key_name];
}
//Check if the value exists
if (in_array($elem[$key_name], $values)===FALSE) {
$array[]=$elem;
}
}
And in your code:
insert_unique_key('codePm',$elem_to_insert,$array_of_elements);
And you have to do it for each element of your array into a new array
--
EDIT: Sorry, this is for insert new unique values into the array, not for obtain the unique values.
Looking at the comments, I think you want only unique values Try this function:
function get_uniques_by_subkey($key_name,$array) {
//Get all elements with the key
$values=array();
foreach ($array as $ii) {
$values[]=$ii[$key_name];
}
//Get the elements that only appeared one time
$count=array_count_values($values);
unset($values);$values=array();
foreach ($count as $key => $n) {
if ($n==1)
$values[]=$key;
}
//Get the values
$out=array();
foreach ($array as $key => $value) {
if (in_array($value[$key_name],$values))
$out[$key]=$value;
}
return $out;
}
You can check the result here: http://codepad.org/QmuoYxsk
Something like this ?
<?
function removeDuplicatesByKey($a, $k) {
$r = array();
$tmp = array();
foreach ($a as $ind => $arr) {
$elem_found = array_search($arr[$k], $tmp);
if ($elem_found === false) {
$tmp[] = $arr[$k];
$r[$ind] = $arr;
} else {
// ok, element found, need to remove both ..
foreach ($r as $index => $r_arr) {
if ($r_arr[$k] == $arr[$k]) {
unset($r[$index]);
}
}
}
}
return $r;
}
$full_arr = array(
'PM-AAA' => array
(
'codePm' => 'PM-32249',
'codeArt' => array(
'0' => 32249
),
'codeArtInFlux' => array(
'0' => 123456
)
)
,
'PM-BBB' => array
(
'codePm' => 'PM-32249',
'codeArt' => array
(
'0' => 33270
),
'codeArtInFlux' => array
(
'0' => 484946
)
)
,
'PM-CCC' => array
(
'codePm' => 'PM-82242',
'codeArt' => array
(
'0' => 82242,
'1' => 82245,
'2' => 82246
),
'codeArtInFlux' => array
(
'0' => 5191,
'1' => 51949,
'2' => 26486
)
)
);
print_r(removeDuplicatesByKey($full_arr, 'codePm'));
?>
Output
Array
(
[1] => Array
(
[codePm] => PM-82242
[codeArt] => Array
(
[0] => 82242
[1] => 82245
[2] => 82246
)
[codeArtInFlux] => Array
(
[0] => 5191
[1] => 51949
[2] => 26486
)
)
)
I made this....on speed mode in my work....you can improve it ;)
$array = array(
'PM-AAA' => array(
'codePm' => 'PM-32249',
'codeArt' => array(32249),
'codeArtInFlux' => array(123456)
),
'PM-BBB' => array(
'codePm' => 'PM-32249',
'codeArt' => array(33270 ),
'codeArtInFlux' => array(484946)
),
'PM-CCC' => array(
'codePm' => 'PM-82242',
'codeArt' => array(82242,82245,82246),
'codeArtInFlux' => array(5191,51949,26486)
)
);
$code_count = array();
$arr2 = array();
foreach($array as $counter) {
$key = $counter['codePm'];
$code_count[] = $key;
}
$arr2 = (array_count_values($code_count));
print_r($arr2); //now i know how many times my code is repeated
while ($code_name = current($arr2)) {
if ($code_name == 1) {
$unique_code = key($arr2);
}
next($arr2);
}
echo $unique_code."</br>"; //i have my unique code
foreach ($array as $key) {
var_dump($key);
if($key['codePm']==$unique_code)
$arr_aux = $key;
}
echo "I have mi array ready with the unique val ;) </br>";
var_dump($arr_aux);
Saludos ;)
Related
I am trying to return the user_id if value matches with any comma separated value, I am using strpos but I don't why is it not working with 3rd case:
To Compare: (This value is stored in $myArray variable)
Array
(
[0] => cloud
[1] => ai
[2] => test
)
Compare with: (This value is stored in $array_meta_values variable)
Array
(
[0] => Array
(
[tags] => cloud,ai
[user_id] => 1
)
[1] => Array
(
[tags] => cloud,ai,test
[user_id] => 108
)
[2] => Array
(
[tags] => storage,backup,ai
[user_id] => 101
)
)
function searchForId($meta_value, $array)
{
foreach ($array as $key => $val) {
if (strpos($val['tags'], $meta_value)) {
return $val['user_id'];
}
}
}
foreach ($myArray as $usertags) {
$userids[] = searchForId($usertags, $array_meta_values);
}
print_r($userids);
Getting this Output:
Array
(
[1] => 1
[2] => 108
)
It was supposed to add 101 as third element in output array but don't know why it is not working.
Any help appreciated.
Hi so I tried to replicate you question,
$existing = ['cloud', 'ai', 'test'];
$checker = [
array(
"tags" => "cloud,ai",
"user_id" => 1
),
array(
"tags" => "cloud,ai,test",
"user_id" => 108
),
array(
"tags" => "storage,backup,ai",
"user_id" => 101
)
];
function searchForId($meta_value, $array)
{
$ret_array = [];
foreach ($array as $val) {
$et = explode(",", $val['tags']);
if (in_array($meta_value, $et)) {
$ret_array[] = $val['user_id'];
}
}
return $ret_array;
}
foreach ($existing as $usertags) {
$userids[$usertags][] = searchForId($usertags, $checker);
}
echo "<pre>";
print_r($userids);
Is this what you looking for?
Your question is quite unclear, but I'll try with this one:
<?php
$myArray = array('cloud', 'ai', 'test');
$array_meta_values = array(
array(
'tags' => 'cloud,ai',
'user_id' => 1,
),
array(
'tags' => 'cloud,ai,test',
'user_id' => 108,
),
array(
'tags' => 'storage,backup,ai',
'user_id' => 101,
),
);
$userids = [];
foreach ($myArray as $value) {
foreach ($array_meta_values as $array) {
$arrayValues = explode(',', $array['tags']);
if (in_array($value, $arrayValues)) {
$userids[$value][] = $array['user_id'];
}
}
}
echo '<pre>';
print_r($userids);
Output:
Array
(
[cloud] => Array
(
[0] => 1
[1] => 108
)
[ai] => Array
(
[0] => 1
[1] => 108
[2] => 101
)
[test] => Array
(
[0] => 108
)
)
This is what I have:
[courses] => array
(
array([id]=>1,[name]=>"course_1",[age]=>16,[location]=>"Berlin"),
array([id]=>2,[name]=>"course_1",[age]=>18,[location]=>"Berlin"),
array([id]=>3,[name]=>"course_1",[age]=>20,[location]=>"Berlin"),
array([id]=>4,[name]=>"course_1",[age]=>16,[location]=>"London"),
array([id]=>5,[name]=>"course_1",[age]=>18,[location]=>"Rome"),
array([id]=>6,[name]=>"course_2",[age]=>16,[location]=>"Berlin")
);
What I need is to transform this into a multidimensional array like this:
- each name can have multiple ages
- each age can have multiple locations
- id is not needed
So the new transformed array should have courses that have multiple ages that have multiple locations.
I first tried to create an array for each key:
// all courses, sorted, once
$x = 0;
$course_names = array();
foreach ($courses as $item) {
$course_names[$x] = $item['name'];
$x++;
}
$course_names = array_unique($course_names);
sort($course_names);
// all ages, sorted, once
$x = 0;
$ages = array();
foreach ($courses as $item) {
$ages[$x] = $item['age'];
$x++;
}
$ages = array_unique($ages);
sort($ages);
// all locations, sorted, once
$x = 0;
$locations = array();
foreach ($courses as $item) {
$locations[$x] = $item['location'];
$x++;
}
$location = array_unique($location);
sort($location);
Then I tried to create another array as requested (don't swear at me, is one of many tries):
$counter = 0;
foreach ($location as $loc_key=>$loc_val) {
foreach ($ages as $age_key=>$age_val) {
foreach ($course_names as $cou_key=>$cou_val) {
foreach ($courses as $course) {
if ($course['name']==$cou_val) {
if ($course['age']==$age_val) {
if ($course['location']==$loc_val) {
$final_json[$counter]['ages']['locations'][] = $loc_val;
}
$final_json[$counter]['ages'][] = $age_val;
}
$final_json[$counter]['id'] = $course['id'];
$final_json[$counter]['name'] = $cou_val;
$counter++;
}
}
}
}
}
The resulted array should be something like this:
[courses] => array
(
[0] => array
(
[name] => "course_1",
[ages] => array
(
[0] => array
(
[age] => 16,
[locations] => array ([0]=>"Berlin",[1]=>"London")
),
[1] => array
(
[age] => 18,
[locations] => array ([0]=>"Berlin",[1]=>"Rome")
),
[2] => array
(
[age] => 20,
[locations] => array ([0]=>"Berlin")
)
)
)
[1] => array
(
[name] => "course_2",
[ages] => array
(
[0] => array
(
[age] => 16,
[locations] => array ([0]=>"Berlin")
)
)
)
);
I'm fighting with this for some time, I feel blocked, any idea is more than welcomed.
$courses = array(
array("id"=>1,"name"=>"course_1","age"=>16,"location"=>"Berlin"),
array("id"=>2,"name"=>"course_1","age"=>18,"location"=>"Berlin"),
array("id"=>3,"name"=>"course_1","age"=>20,"location"=>"Berlin"),
array("id"=>4,"name"=>"course_1","age"=>16,"location"=>"London"),
array("id"=>5,"name"=>"course_1","age"=>18,"location"=>"Rome"),
array("id"=>6,"name"=>"course_2","age"=>16,"location"=>"Berlin"),
);
foreach ($courses as $item) {
$course_age[] = $item['age'];
$course_names[] = $item['name'];
$course_location[] = $item['location'];
}
$course_age = array_unique($course_age);
$course_names = array_unique($course_names);
$course_location = array_unique($course_location);
$finalArray = array();
$finalArrayKey=0;
foreach ($course_names as $key => $courseValue) {
foreach ($courses as $key => $actualValue) {
if($actualValue['name']==$courseValue){
$finalArray[$finalArrayKey]['name'] = $courseValue;
$finalArray[$finalArrayKey]['ages'] = array();
$finalArray[$finalArrayKey]['ages']['location'] = array();
}
}
foreach ($courses as $key => $actualValue) {
if($actualValue['name']==$courseValue){
if(!in_array($actualValue['age'], $finalArray[$finalArrayKey]['ages']))
$finalArray[$finalArrayKey]['ages'][] = $actualValue['age'];
if(!in_array($actualValue['location'], $finalArray[$finalArrayKey]['ages']['location']))
$finalArray[$finalArrayKey]['ages']['location'][] = $actualValue['location'];
}
}
++$finalArrayKey;
}
echo "<pre>";
print_r($finalArray);
Sample Output:
Array
(
[0] => Array
(
[name] => course_1
[ages] => Array
(
[location] => Array
(
[0] => Berlin
[1] => London
[2] => Rome
)
[0] => 16
[1] => 18
[2] => 20
)
)
[1] => Array
(
[name] => course_2
[ages] => Array
(
[location] => Array
(
[0] => Berlin
)
[0] => 16
)
)
)
For simplicity sake decided to modify the output of the finalArray.
The new finalArray would look like this:
Array
(
[course_1] => Array
(
[ages] => Array
(
[16] => Array
(
[locations] => Array
(
[0] => Berlin
[1] => London
)
),
[18] => Array
(
[locations] => Array
(
[0] => Berlin
[1] => Rome
)
),
[20] => Array
(
[locations] => Array
(
[0] => Berlin
)
)
)
),
[course_2] => Array
(
[ages] => Array
(
[16] => Array
(
[locations] => Array
(
[0] => Berlin
)
)
)
)
)
This is the code:
foreach ($courses as $item) {
$course_names[] = $item['name'];
}
$course_names = array_unique($course_names);
sort($course_names);
$finalArray = array();
foreach ($course_names as $key => $courseValue) {
foreach ($courses as $key => $actualValue) {
if($actualValue['name']==$courseValue) {
$finalArray[$courseValue] = array();
$finalArray[$courseValue]['id'] = $actualValue['id'];
$finalArray[$courseValue]['ages'] = array();
}
}
foreach ($courses as $key => $actualValue) {
if($actualValue['name']==$courseValue) {
if(!array_key_exists($actualValue['age'],$finalArray[$courseValue]['ages'])) {
$finalArray[$courseValue]['ages'][$actualValue['age']] = array ();
}
}
}
}
foreach ($finalArray as $course_name=>$arr) {
foreach ($arr['ages'] as $age=>$arr2) {
foreach($courses as $item) {
if($item['name'] == $course_name && $item['age'] == $age && !in_array($item['location'], $finalArray[$course_name]['ages'][$age]['locations'])) {
$finalArray[$course_name]['ages'][$age]['locations'][] = $item['location'];
}
}
}
}
Not sure exactly what format you're looking for, but have a look at this:
$courses = array
(
array('id'=>1, 'name' =>"course_1",'age'=>16,'location'=>"Berlin"),
array('id'=>2,'name'=>"course_1",'age'=>18,'location'=>"Berlin"),
array('id'=>3,'name'=>"course_1",'age'=>20,'location'=>"Berlin"),
array('id'=>4,'name'=>"course_1",'age'=>16,'location'=>"London"),
array('id'=>5,'name'=>"course_1",'age'=>18,'location'=>"Rome"),
array('id'=>6,'name'=>"course_2",'age'=>16,'location'=>"Berlin")
);
$newCourses = [];
foreach ($courses as $item){
$newCourses[$item['name']]['ages'][$item['age']]['locations'][] = $item['location'];
}
$newCourses will be:
array (
'course_1' =>
array (
'ages' =>
array (
16 =>
array (
'locations' =>
array (
0 => 'Berlin',
1 => 'London',
),
),
18 =>
array (
'locations' =>
array (
0 => 'Berlin',
1 => 'Rome',
),
),
20 =>
array (
'locations' =>
array (
0 => 'Berlin',
),
),
),
),
'course_2' =>
array (
'ages' =>
array (
16 =>
array (
'locations' =>
array (
0 => 'Berlin',
),
),
),
),
)
Even if this isn't the format you're after you could probably play with it to get it how you want.
I'm going crazy with this.
So, let's say I got this array:
Array
(
[0] => Array
(
[variation_name] => variation_1
[license_type] => Array
(
[slug] => license_x
[price] => price_x
[dimensions] => dimensions_x
)
)
[1] => Array
(
[variation_name] => variation_2
[license_type] => Array
(
[slug] => license_y
[price] => price_y
[dimensions] => dimensions_y
)
)
[2] => Array
(
[variation_name] => variation_3
[license_type] => Array
(
[slug] => license_solid_z
[price] => price_z
[dimensions] => dimensions_z
)
)
)
and I want to echo the array values beginning with "license_solid" and the value of the array that contains it.
To have the "license_solid" entries I run the following:
$attribute_pa_licenses = array_column($array, 'license_type');
$attribute_pa_license_slug = array_column($attribute_pa_licenses, 'slug');
foreach ($attribute_pa_license_slug as $value) {
if (0 === strpos($value, 'license_solid')) {
echo $value;
}
}
and it DO works, but I'm not understanding how to echo also the array "containing" $value
in this example it should give variation_3
Rewrite your foreach loop as below:-
foreach ($attribute_pa_license_slug as $value) {
if(!empty($value['license_type']['slug'])){
$slug = $value['license_type']['slug'];
if (strpos($slug, 'license_solid') !== false) {
echo $slug; // echo your matched value
$data[] = $value; // store your array in data array
}
}
}
print_r($data); // print arrays who has valid slug values
Traditional foreach is good for array which structure is known but for large array with unknown structure array iterator is good.
have a look on below two methods
<?php
$array = Array
(
'0' => Array
(
'variation_name' => 'variation_1',
'license_type' => Array
(
'slug' => 'license_x',
'price' => 'price_x',
'dimensions' => 'dimensions_x'
)
),
'1' => Array
(
'variation_name' => 'variation_2',
'license_type' => Array
(
'slug' => 'license_y',
'price' => 'price_y',
'dimensions' => 'dimensions_y'
)
),
'2' => Array
(
'variation_name' => 'variation_3',
'license_type' => Array
(
'slug' => 'license_solid_z',
'price' => 'price_z',
'dimensions' => 'dimensions_z'
)
)
);
//METHOD 1 - For known structured array
foreach($array AS $key => $val) {
$slug = $val['license_type']['slug'];
if (strpos($slug, 'license_solid') !== false) {
$data[] = $array[$key];
}
}
print_r($data);
//METHOD 2 - For unknown structured array (use iterator for unknow and large structured)
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$data = array();
foreach ($it as $key => $val) {
$ar = $it->getSubIterator($it->getDepth() - 1);
if($key == 'slug' && strpos($val, 'license_solid') !== false){
$data[] = (array) $ar;
}
}
print_r($data);
Output:
Array
(
[0] => Array
(
[variation_name] => variation_3
[license_type] => Array
(
[slug] => license_solid_z
[price] => price_z
[dimensions] => dimensions_z
)
)
)
Use foreach over whole array with $key argument:
foreach ($array as $key => $value) {
$slugValue = $value['license_type']['slug'];
if (...) { echo $slugValue; }
// $key contains current array index (0..2 for array in example)
// $value contains array with variation_name, license_type
}
I have a multidimensional array like below:
$data = array (
'department1' =>array(
'user1' => array(
'building1' => array(
'room1' => array(
'active' =>'false'
),
'room2' => array(
)
),
'building2' => array(
'room4' => array(
),
'room3' => array(
)
),
)
)
);
What I am trying to do is to check the room if is null or not. If null I should set a value active => test.
The code I've done so far is:
foreach($data as $departments => $department){
foreach ($department as $users => $user){
foreach($user as $buildings => $building) {
foreach($building as $key => $value){
if ($data[$departments][$users][$buildings][$key] == null) {
$data[$departments][$users][$buildings][$key]['active'] = 'test';
}
}
}
}
}
It's working but I want to know if there is a best other way to implement it without used much foreach.
My output is:
Array
(
[department1] => Array
(
[user1] => Array
(
[building1] => Array
(
[room1] => Array
(
[active] => false
)
[room2] => Array
(
[active] => test
)
)
[building2] => Array
(
[room4] => Array
(
[active] => test
)
[room3] => Array
(
[active] => test
)
)
)
)
)
Any help? Thank you.
Use the following recursive function which is accepting and returning value by reference(can be used with any item deepness/hierarchy):
function &checkRoom(&$data) {
foreach ($data as $k => &$v) {
if (strpos($k, "room") === 0 && empty($v)) $v = ["active" => "test"];
if (is_array($v)) checkRoom($v);
}
return $data;
}
$data = checkRoom($data);
print_r($data);
The output:
Array
(
[department1] => Array
(
[user1] => Array
(
[building1] => Array
(
[room1] => Array
(
[active] => false
)
[room2] => Array
(
[active] => test
)
)
[building2] => Array
(
[room4] => Array
(
[active] => test
)
[room3] => Array
(
[active] => test
)
)
)
)
)
You can use array_walk_recursive() to walk through your $data array without having to foreach on each level of depth.
array_walk_recursive($data, function (&$value, $key) {
if (is_null($value) && $key == 'active') {
$value = 'test';
}
});
The above code example will walk through your $data array and change each item with key 'active' that has value 'NULL' to value 'test'.
Note that the 'active' key has to be set in order for this to work.
Resources
array_walk_recursive() - Manual
i have this array:
[Jessica CS] => Array
(
[2011-04-20] => Array
(
[0] => 69.90
[cancel] => 1311145200
[1] => 29.95
[2] => 69.90
)
)
[Rex CS] => Array
(
[2011-04-20] => Array
(
[0] => 119.94
[cancel] =>
)
[2011-04-26] => Array
(
[0] => 199.50
[cancel] =>
[1] => 29.95
)
....
and i am adding together these values by using a loop:
$i=0;
foreach($dates as $d){
$total[$i] += array_sum($value[$d]);
#i++;
}
this will add everything together and what i want is to exclude the [cancel] field from being added to the array_sum
edit: i could probably add the values that are int, but not sure how to sort them
any ideas?
thanks
Personally I would change the layout of the array so that it went more like:
[Jessica CS] => Array
(
[2011-04-20] => Array
(
[cancel] => 1311145200
[costs] => Array
(
[0] => 69.90
[1] => 29.95
[2] => 69.90
)
)
)
Replacing [costs] with whatever name is most relevant.
Working with your existing array
Failing that
$i=0;
foreach($dates as $d){
$total[$i] += array_sum(array_diff_key($value[$d], array('cancel'));
#i++;
}
Just loop through the array, perhaps like this:
$input = array(
'Jessica CS' => array(
'2011-04-20' => array(
0 => 69.9,
'cancel' => 1311145200,
1 => 29.95,
2 => 69.90,
),
),
'Rex CS' => array(
'2011-04-20' => array(
0 => 119.94,
'cancel' => null,
),
'2011-04-26' => array(
0 => 199.50,
'cancel' => null,
1 => 29.95,
)
)
);
$totals = array();
foreach($input as $person => $dates){
$totals[$person] = 0;
foreach ($dates as $date => $values) {
foreach ($values as $key => $val) {
if ($key !== 'cancel') {
$totals[$person] += $val;
}
}
}
}
print_r($totals)
Produces:
Array
(
[Jessica CS] => 169.75
[Rex CS] => 349.39
)