Related
I have a function with the data I received from json and the student name and surname. I don't have any problems when there is only one student number, but if there are two students in the incoming data, the student number comes in the array. What should I do in this case?
if($adi =="Turkce")
{
$tip = "DuzMantik";
$values = array();
foreach($olan->selections as $solan){
$og_numarasi = $solan->description;
$notum = $solan->note;
$ogrneci_adi = ogrenciadial($yil,$hafta,$og_numarasi);
$values[] = array("tur"=>$og_numarasi,"tid"=>$ogrneci_adi,"not"=>$notum);
}
$array2 = array(
"tip" => $tip,
"id" => 1,
"notlar" => $values,
);
array_push($kod, $array2);
}
ogrenciadial($yil,$hafta,$og_numarasi);
ogrenciadial(1998,5,?);
You can use explode() to turn the comma delimited string into an array.
$og_numarasi = explode(',', $solan->description);
You can then loop through the $og_numarasi array to add each as a new entry into your $values array.
if($adi =="Turkce") {
$tip = "DuzMantik";
$values = array();
foreach($olan->selections as $solan) {
$og_numarasi = explode(',', $solan->description);
$notum = $solan->note;
foreach($og_numarasi as $number) {
$ogrneci_adi = ogrenciadial($yil,$hafta,$number);
$values[] = array("tur"=>$number,"tid"=>$ogrneci_adi,"not"=>$notum);
}
}
$array2 = array(
"tip" => $tip,
"id" => 1,
"notlar" => $values,
);
array_push($kod, $array2);
}
I have a array that looks like this:
$array = [
["444", "0081"],
["449", "0081"],
["451", "0081"],
["455", "2100"],
["469", "2100"]
];
I need to group as a new array that looks like:
array (
0 =>
array (
0 => '444,449,451',
1 => '0081',
),
1 =>
array (
0 => '455,469',
1 => '2100',
),
)
I'd tried many scripts, but with no success.
function _group_by($array, $key) {
$return = array();
foreach($array as $val) {
$return[$val[$key]][] = $val;
}
return $return;
}
$newArray = _group_by($array, 1); // (NO SUCCESS)
There should be more elegant solutions, but simplest one I can think of would be this.
// The data you have pasted in the question
$data = [];
$groups = [];
// Go through the entire array $data
foreach($data as $item){
// If the key doesn't exist in the new array yet, add it
if(!array_key_exists($item[1], $groups)){
$groups[$item[1]] = [];
}
// Add the value to the array
$groups[$item[1]][] = $item[0];
}
// Create an array for the data with the structure you requested
$structured = [];
foreach($groups as $group => $values){
// With the array built in the last loop, implode it with a comma
// Also add the 'key' from the last array to it ($group)
$structured[] = [implode(',', $values), $group];
}
I haven't tested this but something similar should do the trick. This simply goes through the given array and collects all entries in a structurized manner (so $groups variable will contain an array entry for each group sharing a key, and the key will correspond to the 2nd item in each item within the given array). From there it's just about restructuring it to get the format you have requested.
http://php.net/manual/en/control-structures.foreach.php
Writing two loops is too much effort for this task. Use isset() with temporary keys applied to your output array as you iterate. When finished grouping the data, reindex the output with array_values().
Code (Demo)
$array = [
["444", "0081"],
["449", "0081"],
["451", "0081"],
["455", "2100"],
["469", "2100"]
];
foreach ($array as $row) {
if (!isset($result[$row[1]])) {
$result[$row[1]] = $row; // first occurrence of group, save whole row
} else {
$result[$row[1]][0] .= ',' . $row[0]; // not first occurrence, concat first element in group
}
}
var_export(array_values($result));
Or avoid the temporary associative arrays in the result array by using an array of references. (Demo)
$result = [];
foreach ($array as $row) {
if (!isset($ref[$row[1]])) {
$ref[$row[1]] = $row;
$result[] = &$ref[$row[1]];
} else {
$ref[$row[1]][0] .= ',' . $row[0];
}
}
var_export($result);
Or use array_reduce() to enjoy a functional-style technique. (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
if (!isset($result[$row[1]])) {
$result[$row[1]] = $row;
} else {
$result[$row[1]][0] .= ',' . $row[0];
}
return $result;
}
)
)
);
All will output:
array (
0 =>
array (
0 => '444,449,451',
1 => '0081',
),
1 =>
array (
0 => '455,469',
1 => '2100',
),
)
This question already has answers here:
Group 2d array rows by one column and sum another column [duplicate]
(3 answers)
Closed 4 months ago.
I have a multi array that has some duplicated values that are same by name ( name is an element )
i want to sum quantity of each array that has same name , and then unset the second array
Example :
<?php
$Array=array(
0=>array("name"=>"X","QTY"=>500),
1=>array("name"=>"y","QTY"=>250),
2=>array("name"=>"X","QTY"=>250)
);
?>
Now i want to sum duplicated values as below.
Result :
<?php
$Array=array(
0=>array("name"=>"X","QTY"=>750),
1=>array("name"=>"y","QTY"=>250)
);
?>
UPDATED
i found this function to search in array , foreach and another loops does not works too
<?php
function search($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($subarray, $key, $value));
}
}
return $results;
}
?>
<?php
$Array=array(
0=>array("name"=>"X","QTY"=>500),
1=>array("name"=>"y","QTY"=>250),
2=>array("name"=>"X","QTY"=>250)
);
$result = array();
$names = array_column($Array, 'name');
$QTYs = array_column($Array, 'QTY');
$unique_names = array_unique($names);
foreach ($unique_names as $name){
$this_keys = array_keys($names, $name);
$qty = array_sum(array_intersect_key($QTYs, array_combine($this_keys, $this_keys)));
$result[] = array("name"=>$name,"QTY"=>$qty);
}
var_export($result); :
array (
0 =>
array (
'name' => 'X',
'QTY' => 750,
),
1 =>
array (
'name' => 'y',
'QTY' => 250,
),
)
Try this simplest one, Hope this will be helpful.
Try this code snippet here
$result=array();
foreach ($Array as $value)
{
if(isset($result[$value["name"]]))
{
$result[$value["name"]]["QTY"]+=$value["QTY"];
}
else
{
$result[$value["name"]]=$value;
}
}
print_r(array_values($result));
Try this, check the live demo.
<?php
$Array=array(
0=>array("name"=>"X","QTY"=>500),
1=>array("name"=>"y","QTY"=>250),
2=>array("name"=>"X","QTY"=>250)
);
$keys = array_column($Array, 'name');
$QTYs = array_column($Array, 'QTY');
$result = [];
foreach($keys as $k => $v)
{
$result[$v] += $QTYs[$k];
}
print_r($result);
You can achieve this by creating an array with name as key and then iterating over all values and add them together, resulting in this
function sum_same($array) {
$keyArray = [];
foreach ($array as $entry) {
$name = $entry["name"];
if(isset($keyArray[$name])) {
$keyArray[$name] += $entry["QTY"];
} else {
$keyArray[$name] = $entry["QTY"];
}
}
// Convert the keyArray to the old format.
$resultArray = [];
foreach ($keyArray as $key => $value) {
$resultArray[] = ["name" => $key, "QTY" => $value];
}
return $resultArray;
}
Try the code here
If you want to alter the old array use the function like this:
$myArray = sum_same($myArray);
The old array will be overwritten by the new one.
This problem is a classic example of usage for array_reduce():
$Array = array(
0 => array('name' => 'X', 'QTY' => 500),
1 => array('name' => 'y', 'QTY' => 250),
2 => array('name' => 'X', 'QTY' => 250),
);
// array_values() gets rid of the keys of the array produced by array_reduce()
// they were needed by the callback to easily identify the items in the array during processing
$Array = array_values(array_reduce(
$Array,
function (array $a, array $v) {
$k = $v['name'];
// Check if another entry having the same name was already processed
// Keep them in the accumulator indexed by name
if (! array_key_exists($k, $a)) {
$a[$k] = $v; // This is the first entry with this name
} else {
// Not the first one; update the quantity
$a[$k]['QTY'] += $v['QTY'];
}
return $a; // return the partial accumulator
},
array() // start with an empty array as accumulator
));
I have two array in php and now I want to combine this two array as below.
$a1 = Array(
'ansid4' => 4,
'ansid5' => 5,
'ansid6' => 6
);
$a2 = Array(
'value' => 'demo',
'value2' => 'demo2'
);
Required Output:
$target = Array(
4 => 'demo',
5 => 'demo2',
6 => Null
);
Thanks in advance
$resultArray = array();
while ($key = array_pop($arrayOne)) {
$resultArray[$key] = array_pop($arrayTwo);
}
or you could do
$resultArray = array();
foreach ($arrayOne as $key) {
$resultArray[$key] = array_shift($arrayTwo);
}
Both solutions have the disadvantage that they consume one or both arrays.
If you need them still after the combination you could make copies of the Arrays and have those consumed.
Take a look at array_combine
you can send to this function array of keys and array of values and it return assoc array
please notice that the two arrays must have the same number of elements.
if you cant take care of that, try using array_pad before
$targetArray = array('a'=>'','b'=>'');
$sourceArray = array('a'=>array(1,2,3),'c'=>'c','d'=>'d');
$result = array_merge( $targetArray, $sourceArray);
$array_text = recurse_array($result);
echo $array_text;
function recurse_array($values){
$content = '';
if( is_array($values) ){
foreach($values as $key => $value){
if( is_array($value) ){
$content.="$key<br />".recurse_array($value);
}else{
$content.="$key = $value<br />";
}
}
}
return $content;
}
You have to have the same number of elements in both arrays so we start with counting of elements and add necessary NULL values by array_pad
if (count($a1) > count($a2))
{
$a2 = array_pad1($a2, count($a1), NULL);
}
elseif (count($a1) < count($a2))
{
$a1 = array_pad($a1, count($a2), NULL);
}
Then we use array_combine, which creates new array. From both arrays we use values by array_values. From first array we use values as keys and from second array we use values as values:-)
$target = array_combine(array_values($a1), array_values($a2))
This question already has answers here:
Two arrays in foreach loop
(24 answers)
Closed 6 months ago.
ok, assuming I have 5 arrays, all just indexed arrays, and I would like to combine them, this is the best way I can figure, is there a better way to handle this?
function mymap_arrays(){
$args=func_get_args();
$key=array_shift($args);
return array_combine($key,$args);
}
$keys=array('u1','u2','u3');
$names=array('Bob','Fred','Joe');
$emails=array('bob#mail.com','fred#mail.com','joe#mail.com');
$ids=array(1,2,3);
$u_keys=array_fill(0,count($names),array('name','email','id'));
$users=array_combine($keys,array_map('mymap_arrays',$u_keys,$names,$emails,$ids));
this returns:
Array
(
[u1] => Array
(
[name] => Bob
[email] => bob#mail.com
[id] => 1
)
[u2] => Array
(
[name] => Fred
[email] => fred#mail.com
[id] => 2
)
[u3] => Array
(
[name] => Joe
[email] => joe#mail.com
[id] => 3
)
)
EDIT: After lots of benchmarking I wend with a version of Glass Robots answer to handle a variable number of arrays, it's slower than his obviously, but faster than my original:
function test_my_new(){
$args=func_get_args();
$keys=array_shift($args);
$vkeys=array_shift($args);
$results=array();
foreach($args as $key=>$array){
$vkey=array_shift($vkeys);
foreach($array as $akey=>$val){
$result[$keys[$akey]][$vkey]=$val;
}
}
return $result;
}
$keys=array('u1','u2','u3');
$names=array('Bob','Fred','Joe');
$emails=array('bob#mail.com','fred#mail.com','joe#mail.com');
$ids=array(1,2,3);
$vkeys=array('name','email','id');
test_my_new($keys,$vkeys,$names,$emails,$ids);
Personally for readability I would do it this way:
$keys = array('u1','u2','u3');
$names = array('Bob','Fred','Joe');
$emails = array('bob#mail.com','fred#mail.com','joe#mail.com');
$ids = array(1,2,3);
$result = array();
foreach ($keys as $id => $key) {
$result[$key] = array(
'name' => $names[$id],
'email' => $emails[$id],
'id' => $ids[$id],
);
}
I did not check the efficiency, but in my solution I am using only standard functions (they should be optimized) without custom mapping and looping outside them:
// assigning the data from your question
$keys = array('u1','u2','u3');
$names = array('Bob','Fred','Joe');
$emails = array('bob#mail.com','fred#mail.com','joe#mail.com');
$ids = array(1,2,3);
// creating resulting array
$result = array_merge_recursive(
array_combine($keys, $names),
array_combine($keys, $emails),
array_combine($keys, $ids)
);
Did you try this solution?
Here's basically a one-liner for a set number of elements:
$combined = array_combine($keys, array_map(function ($id, $name, $email) {
return compact('id', 'name', 'email');
}, $ids, $names, $emails));
And here a version for PHP 5.2- without anonymous functions:
$combined = array_combine($keys, array_map(create_function('$id, $name, $email',
'return compact("id", "name", "email");'
), $ids, $names, $emails));
For a variable number of elements, it'll look like this:
function combineValues($keys, $values) {
$vKeys = array_keys($values);
return array_combine($keys, array_map(
function ($values) use ($vKeys) { return array_combine($vKeys, $values); },
call_user_func_array('array_map', array_merge(
array(function () { return func_get_args(); }),
$values))));
}
$combined = combineValues($keys, array('name' => $names, 'email' => $emails, 'id' => $ids));
I have to admit that looks pretty cryptic, so here's an expanded version:
function combineValues($keys, $values) {
$valueKeys = array_keys($values);
$combinedValues = call_user_func_array('array_map', array_merge(array(function () { return func_get_args(); }), $values));
$combinedValues = array_map(function ($values) use ($valueKeys) { return array_combine($valueKeys, $values); }, $combinedValues);
return array_combine($keys, $combinedValues);
}
For PHP 5.2- this may look like this:
function combineValues($keys, $values) {
$result = call_user_func_array('array_map', array_merge(
array(create_function('', 'return func_get_args();')),
$values));
array_walk($result,
create_function('&$val, $i, $keys', '$val = array_combine($keys, $val);'),
array_keys($values));
return array_combine($keys, $result);
}
Simply try this for multiples array combine (if you have length of arrays)
$array_id = array ('1', '2', '3');
$array1 = array ('arr1_value1', 'arr1_value2', 'arr1_value3');
$array2 = array ('arr2_value1', 'arr2_value2', 'arr2_value3');
$array3 = array ('arr3_value1', 'arr3_value2', 'arr3_value3');
$lenght = count($array_id);
$i = 0;
while ($i < $lenght) {
$result[] = array(
$array_id[$i]
, $array1[$i]
, $array2[$i]
, $array3[$i]
);
$i++;
}
echo '<pre>';
print_r($result);