I need to merge arrays into 1 array but what I need is to remove before the main data they b oth have in common (duplicated values i mean), I need only unique values when merged.
array formed from foreach.
public $arrayfields= [];
public $itemMap = [];
public function getRowMapping(array $row,$uniqueField,$moduleName)
{
$arrayData = [];
foreach ($this->columnMapping as $key => $value) {
$row = $this->moduleType($key,$value,$row,$moduleName);
}
$unique = $row[$uniqueField];
if(!isset($this->itemMap[$unique])){
$this->itemMap[$unique] = $row;
$this->itemMap[$unique][$unique]['items'] = [];
}
$this->itemMap[$unique]['items'][] = $row['items'];
return $row;
}
i changed little bit to my input
How can i do that?
so now the input will be like this
Array
(
[bill_type] => 1
[bill_number] => BIL-003
[order_number] => ON-003
[items] => Array
(
[track_inventory] => 0
[sku1] => sku1
[name] => Kidswear1
)
)
Array
(
[bill_type] => 1
[bill_number] => BIL-003
[order_number] => ON-003
[items] => Array
(
[track_inventory] => 0
[sku1] => sku2
[name] => Pant
)
)
Array
(
[bill_type] => 1
[bill_number] => BIL-002
[order_number] => ON-002
[items] => Array
(
[track_inventory] => 0
[sku1] => sku3
[name] => Pants
)
)
The final output I'm looking for is
Array
(
[BIL-003] => Array
(
[bill_type] => 1
[order_number] => ON-003
[items] => Array
(
[0] => Array(
[track_inventory] => 0
[sku1] => sku1
[name] => Kidswear1
)
[1] => Array
(
[track_inventory] => 0
[sku1] => sku2
[name] => Pant
)
)
[BIL-002] => Array
(
[bill_type] => 1
[order_number] => ON-002
[items] => Array
(
[0] => Array(
[track_inventory] => 0
[sku1] => sku3
[name] => pants
)
)
)~~~
I think there is no standard library function to accomplish this.
So here is the function that accomplishes this:
function merge($array1, $array2)
{
$arraymerged = [];
if (is_array($array1) && is_array($array2)) {
//collect the keys of two arrays
$keys = [];
foreach ($array1 as $key => $value) {
$keys[$key] = true;
}
foreach ($array2 as $key => $value) {
$keys[$key] = true;
}
//merge key values for each key
foreach ($keys as $key => $value) {
if (isset($array1[$key]) && isset($array2[$key])) {
if ($array1[$key] == $array2[$key]) {
$arraymerged[$key] = $array1[$key];
} else {
$arraymerged[$key] = [$array1[$key], $array2[$key]];
}
} else if (isset($array1[$key]))
$arraymerged[$key] = $array1[$key];
else
$arraymerged[$key] = $array2[$key];
}
return $arraymerged;
}
}
Here is my suggestion,
if the input is array, check my answer on this post Convert an associative array into an associative array which has a key with another associative array as its value in php
otherwise check below code.
bill_number as unique key and run foreach and append items array elements.
let me give you an example
$arr1 = [
"bill_type" => 1,
"bill_number" => 'BIL-003',
"items"=>[
0 => [
"name"=>"test"
]
]
];
$arr2 = [
"bill_type" => 1,
"bill_number" => 'BIL-003',
"items"=>[
0 => [
"name"=>"test_2"
]
]
];
$formattedArr = [];
//merge these arrays
$combinedArr = [];
$combinedArr[] = $arr1;
$combinedArr[] = $arr2;
foreach($combinedArr as $key=>$value){
$formattedArr[$value['bill_number']]["bill_type"] = $value["bill_type"];
$formattedArr[$value['bill_number']]["items"][] = $value["items"];
}
print_r($formattedArr);
I haven't tested this code, but i think this will be ans to your question.
<?php
$a1 = array(
"bill_type" => "1",
"bill_number" => "BIL-003",
"order_number" => "ON-003",
"items" => array(
"track_inventory" => "0",
"sku1" => "sku1",
"name" => "Kidswear1"
)
);
$a2 = array(
"bill_type" => "1",
"bill_number" => "BIL-003",
"order_number" => "ON-003",
"items" => array(
"track_inventory" => "0",
"sku1" => "sku2",
"name" => "Pant"
)
);
$result = function ($a1, $a2) {
$b1 = $a1['items'];
$b2 = $a2['items'];
$c1 = $a1;
$c2 = $a2;
unset($c1['items']);
unset($c2['items']);
if (count(array_diff($c1, $c2)) == 0) {
if (count(array_diff($b1, $b2)) != 0) {
$c1['items'] = [$b1, $b2];
} else {
$c1['items'] = $b1;
}
return $c1;
}else{
//you should complete this part by yourself, if first parts are not equal.
}
return $c1;
};
$r = $result($a1, $a2);
var_dump($r);
result:
(array) [4 elements]
bill_type: (string) "1"
bill_number: (string) "BIL-003"
order_number: (string) "ON-003"
items:
(array) [2 elements]
0:
(array) [3 elements]
track_inventory: (string) "0"
sku1: (string) "sku1"
name: (string) "Kidswear1"
1:
(array) [3 elements]
track_inventory: (string) "0"
sku1: (string) "sku2"
name: (string) "Pant"
Related
How to update an array of objects, adding the quantities if you already have the same ID, or if you have not created a new object.
I tried to explain in the code with the arrays and also with the idea of how I would like the result to be.
old Array
$a1 = [
array(
"id" => 1,
"qty" => 1
),
array(
"id" => 2,
"qty" => 1
)
];
$a2 = [
array(
"id" => 1,
"qty" => 1
)
];
$output = array_merge($a1, $a2);
echo '<pre>';
print_r($output);
echo '</pre>';
Result Error:
Array
(
[0] => Array
(
[id] => 1
[qty] => 1
)
[1] => Array
(
[id] => 2
[qty] => 1
)
[2] => Array
(
[id] => 1
[qty] => 1
)
)
What I need, in addition to if the ID does not contain, add.
Array
(
[0] => Array
(
[id] => 1
[qty] => 2
)
[1] => Array
(
[id] => 2
[qty] => 1
)
)
You can take the first array as base, then search for the key (if existing) where the product matches the id. Then either add the quantity and recalculate the price or you just add the reformatted element (id to product conversion).
$result = $a;
foreach($b as $element) {
$matchingProductIndex = array_search($element['id'], array_column($a, 'product'));
if ($matchingProductIndex !== false) {
$pricePerUnit = $result[$matchingProductIndex]['price'] / $result[$matchingProductIndex]['qty'];
$result[$matchingProductIndex]['qty'] += $element['qty'];
$result[$matchingProductIndex]['price'] = $result[$matchingProductIndex]['qty'] * $pricePerUnit;
} else {
$result[] = [
'qty' => $element['qty'],
'product' => $element['id'],
'price' => $element['price'],
];
}
}
print_r($result);
Working example.
Loop through both arrays with foreach and check the ids against each other.
https://paiza.io/projects/lnnl5HeJSFIOz_6KD6HRIw
<?php
$arr1 = [['qty' => 4, 'id' => 4],['qty' => 1,'id' => 30]];
$arr2 = [['id' => 30, 'qty' => 19],['id' => 31, 'qty' => 2]];
$arr3 = [];
foreach($arr1 as $iArr1){
$match = false;
foreach($arr2 as $iArr2){
if($iArr1['id'] === $iArr2['id']){
$arr3[] = ['id' => $iArr1['id'], 'qty' => $iArr1['qty'] + $iArr2['qty']];
$match = true;
}
}
if(!$match){
$arr3[] = $iArr1;
$arr3[] = $iArr2;
}
}
print_r($arr3);
?>
One approach could be one I more often suggested.
First lets merge $a2 with one to simplify looping over one larger collection.
If we then create a small mapping from id to its index in the result array we can update the running total of qty.
$map = [];
$result = [];
// Merge the two and do as per usual, create a mapping
// from id to index and update the qty at the corresponding index.
foreach (array_merge($a1, $a2) as $subarr) {
$id = $subarr['id'];
if (!key_exists($id, $map)) {
$index = array_push($result, $subarr) - 1;
$map[$id] = $index;
continue;
}
$result[$map[$id]]['qty'] += $subarr['qty'];
}
echo '<pre>', print_r($result, true), '</pre>';
Output:
Array
(
[0] => Array
(
[id] => 1
[qty] => 2
)
[1] => Array
(
[id] => 2
[qty] => 1
)
)
I have an arrays like this
Array
(
[original_data] => Array
(
[0] => Array
(
[reference_id] => 122
[id] => 121
[reference_name] => Dinesh
)
[1] => Array
(
[reference_id] => 123
[id] => 120
[reference_name] => Dinesh Test
)
)
[edited_data] => Array
(
[0] => Array
(
[reference_id] => 123
[id] => 120
[reference_name] => Dinesh Test2
)
)
)
I want to get the difference between this original_data and edited_data arrays. How to do that? I tried using array_diff. But, It didn't work correctly.
You can get the difference =>
$result = ref_array_diff($requestedData['edited_data'], $requestedData['data']);
print_r($result);
function ref_array_diff($arraya, $arrayb) {
foreach ($arraya as $keya => $valuea) {
if (in_array($valuea, $arrayb)) {
unset($arraya[$keya]);
}
}
return $arraya;
}
If you use array_map on both original data and edited data to get an array of original_data id values and edited_data id values. You can then use array_diff with no problem. Using the resulting list of id's which are in one but not the other you can lookup the original value using the array mapped values index key on the original arrays.
I'm making the assumption here that your id key is a unique identifier for each value in the data arrays. If this isn't the case you'll need to do some nested loops to compare deep values
This should work.
<?php
// your data
$data = array (
'original_data' => array
('0' => array
(
'reference_id' => 122,
'id' => 121,
'reference_name' => 'Balasuresh,'
),
'1' => array
(
'reference_id' => 123,
'id' => 120,
'reference_name' => 'Balasuresh',
),
),
'edited_data' => array
('0' => array
(
'reference_id' => 123,
'id' => 120,
'reference_name' => 'Balasuresh Test',
),
)
) ;
// let's get our reference_ids
$originalData = array() ;
foreach($data['original_data'] as $entry) {
$originalData[$entry['reference_id']] = $entry ;
}
// let's compare our edited data to our original data
$editedData = array() ;
foreach($data['edited_data'] as $editedEntry) {
if (isset($originalData[$editedEntry['reference_id']])) {
// for readability
$compare = $originalData[$editedEntry['reference_id']] ;
foreach($editedEntry as $key=>$value) {
if ($compare[$key] != $value) {
$editedData[$editedEntry['reference_id']][$key] = $value ;
}
}
}
}
$editedData now contains your differences
These are multi-dimensional associative arrays, you can recursively do an array_diff_assoc like this:
you can check this code here https://3v4l.org/ovaQB:
function array_diff_assoc_recursive($array1, $array2)
{
foreach($array1 as $key => $value)
{
if(is_array($value))
{
if(!isset($array2[$key]))
{
$difference[$key] = $value;
}
elseif(!is_array($array2[$key]))
{
$difference[$key] = $value;
}
else
{
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
if($new_diff != FALSE)
{
$difference[$key] = $new_diff;
}
}
}
elseif(!isset($array2[$key]) || $array2[$key] != $value)
{
$difference[$key] = $value;
}
}
return !isset($difference) ? 0 : $difference;
}
$a=["original_data"=>[
[
'reference_id' => 122,
'id' => 121,
'reference_name' => 'Balasuresh'
],[
'reference_id' => 123,
'id' => 120,
'reference_name' => 'Balasuresh'
]
],
'edited_data' => [[
'reference_id' => 123,
'id' => 120,
'reference_name' => 'Balasuresh Test'
]]
];
print_r(array_diff_assoc_recursive($a['edited_data'], $a['original_data']));
output:
Array
(
[0] => Array
(
[reference_id] => 123
[id] => 120
[reference_name] => Balasuresh Test
)
)
I have two multidimensional array
Array
(
[0] => Array
(
[code] => 2079
[label] => Nike
)
[1] => Array
(
[code] => 1080
[label] => Adidas
)
)
Array
(
[0] => Array
(
[manufacturers_id] => 2753
[manufacturers_name] => Reebok
)
[1] => Array
(
[manufacturers_id] => 2526
[manufacturers_name] => Adidas
)
[2] => Array
(
[manufacturers_id] => 34
[manufacturers_name] => Nike
)
)
I want to do string matching of a key label of array 1 with key manufacturer_name of array 2. What is the best approach in multidimensional arrays ?
You could loop trough the arrays.
foreach ($multi_array1 as $value) {
foreach ($multi_array2 as $value2) {
If ($value[label] === $value2 [manufacturer_name])
{}
}
}
If you want to match by label and manufacturers_name, then I suggest you reindex your arrays by those fields:
$by_label = [];
foreach($first_array as $element) {
$by_label[$element['label']] = $element['code'];
}
$by_name = [];
foreach($second_array as $element) {
$by_label[$element['manufacturers_name']] = $element['manufacturers_id'];
}
foreach($by_label as $label => $code) {
print "Label is $label, code is $code, id is {$by_name[$label]}";
}
foreach($by_name as $name => $id) {
print "Name is $name, id is $id, label is {$by_label[$name]}";
}
Just use foreach to accomplish your desire result.
Array
$firstArr = array(
array("code" => 2079, "label" => 'Nike'),
array("code" => 1080, "label" => 'Adidas')
);
$secArr = array(
array("manufacturers_id" => 2753, "manufacturers_name" => 'Reebok'),
array("manufacturers_id" => 2526, "manufacturers_name" => 'Adidas'),
array("manufacturers_id" => 34, "manufacturers_name" => 'Nike')
);
Foreach Technique:
foreach($firstArr as $value){
if(in_array_sec($value['label'])){
echo $value['label'].' found in second array.';
}else{
echo $value['label'].' not found in second array.';
}
}
function in_array_sec($val_one){
global $secArr;
$flag = false;
foreach($secArr as $value){
if($value['manufacturers_name'] == $val_one){
$flag = true;
break;
}
else
$flag = false;
}
return $flag;
}
Result:
Nike found in second array.
Adidas found in second array.
I have an array within an array like this:
Array
(
[0] => Array
(
[name] => B
[id] => 924572
)
[1] => Array
(
[name] => A
[id] => 120689
)
[2] => Array
(
[name] => A
[id] => 120689
)
[3] => Array
(
[name] => C
[id] => 919644
)
[4] => Array
(
[name] => A
[id] => 120689
)
[5] => Array
(
[name] => B
[id] => 924572
)
)
How can I get the most repeated value from object named name and id?
I've already tried the code below but I'm getting an error: Warning: array_count_values(): Can only count STRING and INTEGER values!
$count = array_count_values($info);
arsort($count);
$popular = array_keys($count);
echo $popular[0];
Any fix regarding to this problem?
"Serializing way" for searching most repeated couples (name,id):
$out = array();
foreach($arr as $el){
$key = serialize($el);
if (!isset($out[$key]))
$out[$key]=1;
else
$out[$key]++;
}
arsort($out);
foreach($out as $el=>$count){
$item = unserialize($el);
echo "Name = ".$item['name'].' ID = '.$item['id'].' Count = '.$count.'<br/>';
}
Output:
Name = A ID = 120689 Count = 3
Name = B ID = 924572 Count = 2
Name = C ID = 919644 Count = 1
update Without loop
.....
arsort($out);
$most = unserialize(key($out));
$most_count = array_shift($out);
echo $most['name'];
echo $most['id'];
echo $most_count;
Output:
A
120689
3
A more linear solution.
$arr = Array
(
Array
(
"name" => "B",
"id" => 924572
),
Array
(
"name" => "A",
"id" => 120689
),
Array
(
"name" => "A" ,
"id" => 120689
),
Array
(
"name" => "C",
"id" => 919644
),
Array
(
"name" => "A",
"id" => 120689
),
Array
(
"name" => "B",
"id" => 924572
));
$countArr = Array();
for($i = 0; $i < count($arr); $i++)
{
$tmpArr = $arr[$i];
if(array_key_exists($tmpArr["name"],$countArr))
$countArr[$tmpArr["name"]]++;
else
$countArr[$tmpArr["name"]] = 0;
}
arsort($countArr);
var_dump($countArr);
Maybe you can work with this solution:
<?php
$info = array(
array(
"name" => "B",
"id" => 924572
),
array(
"name" => "A",
"id" => 120689
),
array(
"name" => "A",
"id" => 120689
),
array(
"name" => "C",
"id" => 919644
),
array(
"name" => "A",
"id" => 120689
),
array(
"name" => "B",
"id" => 924572
),
);
$result = array();
foreach ($info as $infoKey => $infoValue) {
foreach ($infoValue as $itemKey => $itemValue) {
if ($itemKey != "name") {
continue;
}
if (array_key_exists($itemValue, $result)){
$result[$itemValue]++;
continue;
}
$result[$itemValue] = 1;
}
}
arsort($result);
var_dump($result);
Will result in:
array (size=3)
'A' => int 3
'B' => int 2
'C' => int 1
Based on finding the mode and mapping in PHP. Would this work?
$name_array = array_map(function($x) {return $x["name"];}, $info);
$count = array_count_values($name_array);
$mode = array_keys($count, max($count));
To return an array of "name", "id" pairs use:
$return_value = array_filter($info, function($x) use ($mode) { return (in_array($x["name"], $mode));});
Makes use of array_column (requires PHP 5.5 or shim).
$count_values = array_count_values(array_column($array, 'name'));
$most_frequent_name = array_search(max($count_values), $count_values);
Then if you want all arrays with this name:
$items = array_filter($array, function ($v) use ($most_frequent_name) {
return $v['name'] == $most_frequent_name;
});
If several names may have the same top frequency:
$count_values = array_count_values(array_column($array, 'name'));
$most_frequent_names = array_keys($count_values, max($count_values));
$items = array_filter($array, function ($v) use ($most_frequent_names) {
return in_array($v['name'], $most_frequent_names);
});
Try following code. It will give you count of occurrences of all elements
function array_icount_values($arr,$lower=true) {
$arr2=array();
if(!is_array($arr['0'])){$arr=array($arr);}
foreach($arr as $k=> $v){
foreach($v as $v2){
if($lower==true) {$v2=strtolower($v2);}
if(!isset($arr2[$v2])){
$arr2[$v2]=1;
}else{
$arr2[$v2]++;
}
}
}
return $arr2;
}
$arr = array_icount_values($array);
echo "<pre>";
print_r($arr);
I have two array and I need to merge it together !!
Array 1
Array
(
[0] => Array
(
[brand] => CARTIER
[amount_2014] => 136476
)
[1] => Array
(
[brand] => TIFFANY & CO.
[amount_2014] => 22000
)
[2] => Array
(
[brand] => Test
[amount_2014] => 33000
)
)
Array 2
Array
(
[0] => Array
(
[brand] => CARTIER
[amount_2013] => 22052
)
[1] => Array
(
[brand] => Test
[amount_2013] => 3313
)
)
I need the result array as:
Array
(
[0] => Array
(
[brand] => CARTIER
[amount_2014] => 136476
[amount_2013] => 22052
)
[1] => Array
(
[brand] => TIFFANY & CO.
[amount_2014] => 22000
[amount_2013] => 0
)
[2] => Array
(
[brand] => Test
[amount_2014] => 33000
[amount_2013] => 3313
)
)
So for every [brand] I need the amount in [amount_2014] & [amount_2013], if any one is not present then I need it value as 0;
I am using CodeIgniter for this project, I have only one table with field (brand, amount, year) am issuing two queries for getting sum of amount for 2013 & 2014.
(I am fighting with array_merge and array_combine but no use for me in this case, if any one can help with query then it's also very much helpful).
Try this:
function cars_array_merge()
{
$arrays = func_get_args();
foreach ($arrays as &$array)
{
$new_arr = array();
foreach ($array as $value)
{
$brand = $value['brand'];
unset($value['brand']);
$new_arr[$brand] = $value;
}
$array = $new_arr;
}
$arrays = call_user_func_array('array_merge_recursive', $arrays);
foreach ($arrays as $brand => &$array)
$array['brand'] = $brand;
return array_values($arrays);
}
// testing
$arr1 = [
[ 'brand' => 'CARTIER', 'mount_2014' => 136476 ],
[ 'brand' => 'TIFFANY & CO.', 'mount_2014' => 22000 ]
];
$arr2 = [
[ 'brand' => 'CARTIER', 'mount_2013' => 22052 ]
];
print_r(cars_array_merge($arr1, $arr2));
Output:
Array
(
[0] => Array
(
[mount_2014] => 136476
[mount_2013] => 22052
[brand] => CARTIER
)
[1] => Array
(
[mount_2014] => 22000
[brand] => TIFFANY & CO.
)
)
<?php
for ($i = 0, $max = count($arr1); $i < $max; ++$i) {
$arr1[$i]['amount_2013'] = isset($arr2[$i]['amount_2013']) ? $arr2[$i]['amount_2013'] : 0;
}
$merge = array_merge($arr1, $arr2);
$temp = $merge;
$newArr = array(); $key_array = array();
foreach($merge as $key=>$val){
$b = $val['brand'];
$a1 = isset($val['amount_2013']) ? $val['amount_2013'] : 0;
$a2 = isset($val['amount_2014']) ? $val['amount_2014'] : 0;
unset($temp[$key]);
foreach($temp as $k=>$values){
if($values['brand'] == $b){
if($a1 == 0){
$a1 = isset($values['amount_2013']) ? $values['amount_2013'] : 0;
}
if($a2 == 0){
$a2 = isset($values['amount_2014']) ? $values['amount_2014'] : 0;
}
unset($temp[$k]);
}
}
if(!in_array($b, $key_array))
{
$newArr[] = array('brand' => $b, 'amount_2014' => $a2, 'amount_2013' => $a1);
}
$key_array[] = $b;
}
print_r($newArr);
This is what I used:
<?php
$arr1 = array(0=>array("brand"=>"CARTIER","amount_2014"=>136476), 1=>array("brand"=>"tiffany","amount_2014"=>22000));
$arr2 = array(0=>array("brand"=>"CARTIER","amount_2013"=>22000));
foreach ($arr2 as $key=>$value){
if( $value["brand"] == "CARTIER")
{
$arr1[0]["amount_2013"] = $value["amount_2013"];
$arr1[1]["amount_2013"] = 0;
}
else
{
$arr1[1]["amount_2013"] = $value["amount_2013"];
$arr1[0]["amount_2013"] = 0;
}
}
print_r($arr1);
?>