Compare two arrays (Stock inventory) - php

For a cars company (Just an example) I need to automate the stock inventory:
$purchase_array = array("Lamborghini" => "5", "Ferrari" => "4", "Bugatti" => "3", "McLaren" => "2", "Fiat" => "10", "Mazda" => "20");
$sales_array = array("Lamborghini" => "1", "Ferrari" => "2", "Bugatti"
=> "3");
I want to have as results this array:
$stock_array = array("Lamborghini" => "4", "Ferrari" => "2", "Bugatti"
=> "0", "McLaren" => "2", "Fiat" => "10", "Mazda" => "20");
First I looked for the common cars:
$common_cars = array_keys(array_intersect_key($purchase_array, $sales_array));
foreach ($common_cars as $common_car) {
.....
}
buy I couldn't finish it.
Any help will be appreciated.
Thanks in advance

You could do something similar to this. If you wanted to preserve the purchase_array you could copy the array to another var.
N.B. If you could retrieve/store the quantity as intergers you can be sure when you loop over the items you wont get an unexpected result
$aPurchaseArray = array("Lamborghini" => 5, "Ferrari" => 4, "Bugatti" => 3, "McLaren" => 2, "Fiat" => 1", "Mazda" => 2");
$aSalesArray = array("Lamborghini" => 1, "Ferrari" => 2, "Bugatti" => 3);
// foreach sales item, using the key as the name and value as quantity sold
foreach($aSalesArray as $sProductName => $iQuantitySold){
// if the product name exists in the target reduce its quantity
if(isset($aPurchaseArray[$sProductName])){
$aPurchaseArray[$sProductName] - $iQuantitySold;
}
}

Related

PHP efficient way to combine two associative arrays into one multidimensional associative array

This is the first problem:
I have two Associative Arrays, one containing sales persons and one containing clients.
$salesPersons = array(
array(
"id" => "1",
"name" => "Mr Smith",
"email" => "mrsmith#email.com",
"clients" => array()
),
array(
"id" => "2",
"name" => "James Bond",
"email" => "jamesbond#email.com",
"clients" => array()
)
);
$clients = array(
array(
"id" => "1",
"name" => "Lucifer Enterprises",
"salesPersonId" => "1"
),
array(
"id" => "2",
"name" => "Charlies Chocolate Factory",
"salesPersonId" => "1"
),
array(
"id" => "3",
"name" => "Geckos Investments",
"salesPersonId" => "2"
),
);
I want to map $salesPersons['id'] to clients['salesPersonId'] by ID and return a multidimensional associative array like this:
$result_i_want = array(
array(
"id" => "1",
"name" => "Mr Smith",
"email" => "mrsmith#email.com",
"clients" => array(
array(
"id" => "1",
"name" => "Lucifer Enterprises",
),
array(
"id" => "2",
"name" => "Charlies Chocolate Factory",
),
)
),
array(
"id" => "2",
"name" => "James Bond",
"email" => "jamesbond#email.com",
"clients" => array(
array(
"id" => "3",
"name" => "Geckos Investments",
),
)
)
);
My solution to the first problem
I have solved it using nested foreach-loops and array_push
$result = array();
foreach ($clients as $c_record) {
foreach ($salesPersons as $s_record) {
if ($c_record['salesPersonId'] == $s_record['id']) {
array_push($s_record['clients'], array(
"id" => $c_record['id'],
"name" => $c_record['name']
));
array_push($result, $s_record);
}
}
}
The remaining problem
This solution doesn't seem to be very efficient.
For each client record I check all sales persons to see if there is a match. I think the number of computations are:
no. of clients * no. of sales persons
I have a huge database and also need to add even more dimensions by mapping projects to the clients and deliverables to the projects. I think this could pose a problem.
Question
Is there a more efficient way to get the same result?
Build an index :
you need to access your salesPerson entries by id, you can start by creating an associative array id => salesPerson, and then use this associative array in your loop.
$salesById = array();
foreach ($salesPersons as $s_record) {
$salesById[ $s_record['id'] ] = $s_record;
}
$result = array();
foreach ($clients as $c_record) {
$s_record = $salesById[ $c_record['salesPersonId'] ];
if ($s_record == null) {
// you may want to handle invalid ids in the client array
// one way is to simply ignore this client record :
continue;
}
array_push($s_record['clients'], array(
"id" => $c_record['id'],
"name" => $c_record['name']
));
array_push($result, $s_record);
}
Notes
There may be a problem in the way you create your $result array :
if a sales person has n clients, the $result array will reference that sales person n times.
Look closer into what result you actually want, you may simply want to return $salesPersons, or $salesById.
As LeGEC said:
you need to access your salesPerson entries by id, you can start by creating an associative array id => salesPerson, and then use this associative array in your loop.
You need to set the index of your arrays with the id:
<?php
$salesPersons = array(
1 => array(
"id" => "1",
"name" => "Mr Smith",
"email" => "mrsmith#email.com",
"clients" => array()
),
2 => array(
"id" => "2",
"name" => "James Bond",
"email" => "jamesbond#email.com",
"clients" => array()
)
);
$clients = array(
1 => array(
"id" => "1",
"name" => "Lucifer Enterprises",
"salesPersonId" => "1"
),
2 => array(
"id" => "2",
"name" => "Charlies Chocolate Factory",
"salesPersonId" => "1"
),
3 => array(
"id" => "3",
"name" => "Geckos Investments",
"salesPersonId" => "2"
),
);
Then:
$result = array();
foreach ($clients as $id => $c_record) {
if (isset($salesPersons[$id])) {
$result[] = array_merge($clients[$id], $salesPersons[$id]);
} else {
$result[] = $clients[$id];
}
}
var_dump($result);
Result here: http://sandbox.onlinephpfunctions.com/code/e590bdb5aaea2794fc5a04ee60f61db766129664
PS:
My code works with your use case, but it will not work if the size of the $salesPersons array is bigger than the $clients array

Manipulate values of a two-dimensional array and find the highest value using only for loop

How can I find the highest value in the sales key, for this case will be 21, using only "for loop"?
I have been trying to get the values for the sales index in order to find which sale had the highest value, however everything I do, its just simply to run all the array elements and show them into the screen.
$Vehicles = [
"v1" => [
"name" => "Audi",
"model" => "2019",
"sales" => 21
],
"v2" => [
"name" => "BMW",
"model" => "2019",
"sales" => 8
],
"v3" => [
"name" => "Aston Martin",
"model" => "2019",
"sales" => 7
]
];
The highest selling is 21.
key = "sales"
value = 21
Try This
Since PHP 5.5 there is array_column
array_column(array,column_key);
So, in your case to get max value -
$Highest_Selling_Value = max(array_column($Vehicles, 'sales'));
use array_column
max(array_column($Vehicles, 'sales'));

json_encode, associative array needed in [ brackets ]

I'm using PHP, and in order to feed some data to an API using Curl, I need to format some strings and have been using json_encode. It works just fine for simpler bits, but this I can't figure out:
The API expects this:
{
"id": "string",
"startTime": "2017-04-18T08:04:23.167Z",
"endTime": "2017-04-18T08:04:23.167Z",
"contacts": [
{
"id": "string",
"displayName": "string"
}
My code so far:
$data_set_pre = array(
"id" => "",
"startTime" => "2017-04-14T07:47:59.028Z",
"endTime" => "2017-04-15T07:47:59.028Z",
"contacts" => array("id" => "ahashofsomenumbersandletters", "displayName" => "John Doe"),
);
$data_set = json_encode($data_set_pre);
Unfortunately, this produces:
{"id":"","startTime":"2017-04-14T07:47:59.028Z","endTime":"2017-04-15T07:47:59.028Z","contacts":{"id":"ahashofsomenumbersandletters","displayName":"John Doe"}}
I've been researching, and I'm getting the impression that json_encode will encode everything BUT an unbroken sequential array starting from 0 as an object, and I don't now how to work around this.
(No, I can't change what the API requires, it's provided by a 3rd-party).
<?php
$data_set_pre = array(
"id" => "12",
"startTime" => "2017-04-14T07:47:59.028Z",
"endTime" => "2017-04-15T07:47:59.028Z",
"contacts" => array(
array(
"id" => "ahashofsomenumbersandletters", "displayName" => "John Doe"
)
)
);
$data_set = json_encode($data_set_pre);
Change the following line:
"contacts" => array("id" => "ahashofsomenumbersandletters", "displayName" => "John Doe"),
to
"contacts" => array(array("id" => "ahashofsomenumbersandletters", "displayName" => "John Doe")),
It will give:
{"id":"","startTime":"2017-04-14T07:47:59.028Z","endTime":"2017-04-15T07:47:59.028Z","contacts":[{"id":"ahashofsomenumbersandletters","displayName":"John Doe"}]}
here [{"id":"ahashofsomenumbersandletters","displayName":"John Doe"}] is a multi-dimension array

How to convert array from lineal to multidimensional in PHP?

I have the following input array:
$arr = [
"quote_id" => "1",
"ONE" => "2018-03-12",
"TWO" => "2018-02-12",
"THREE" => "2018-01-12",
"FOUR" => "2017-12-12"
];
and I need to transform to the following output:
[
"quote_id" => "1",
"ONE" => "2018-03-12"
],
[
"quote_id" => "1",
"TWO" => "2018-02-12"
],
[
"quote_id" => "1",
"THREE" => "2018-01-12"
],
[
"quote_id" => "1",
"FOUR" => "2017-12-12"
]
The idea is to insert a record in the DB per each COLUMN (ONE, TWO, ...) so I end up with:
INSERT INTO table id=1, value="2018-03-12"
INSERT INTO table id=1, value="2018-02-12"
INSERT INTO table id=1, value="2018-01-12"
INSERT INTO table id=1, value="2017-12-12"
Can I get some help?
Aslong as quote_id is the key that you want inserted every time
foreach ($arr as $key => $value) {
if($key != "quote_id")
{
/* insert $arr["quote_id"], $value */
}
}

What's wrong with this simple code?

I want to compare the 2 arrays below and find the differences. The values for keys "lead owner" and "company" are different, but when I compare these arrays, it says only "company" values are different. But when I create 2 new arrays with only one key/value pair for "lead owner" it works properly. Am I making some mistake?
<?php
$arr1 = Array
(
"leadid" => "418176000000069007",
"smownerid" => "418176000000047003",
"lead owner" => "Amit Patil",
"company" => "SAM",
"first name" => "Test",
"last name" =>"Lead1",
"designation" => "call",
"email" => "",
"phone" => "958",
"fax" => "",
"mobile" => "",
"website" => "www.infosys.con",
"lead source" => "Cold Call",
"lead status" => "Contact in Future",
"industry" => "None",
"no of employees" => "45000",
"annual revenue" => "0",
"rating" => "Active",
"smcreatorid" => "418176000000047003",
"created by" => "Amit Patil",
"modifiedby" => "418176000000047003",
"modified by" => "Amit Patil",
"created time" => "2012-04-05 19:58:00",
"modified time" => "2012-05-02 08:51:08",
"street" => "",
"city" => "",
"state" => "",
"zip code" => "",
"country" => "",
"description" => "",
"skype id" => "",
"email opt out" => "false",
"salutation" => "Mr.",
"secondary email" => ""
);
$arr2 = Array
(
"leadid" => "418176000000069007",
"smownerid" => "418176000000047003",
"lead owner" => "Amit aaa",
"company" => "SAM A",
"first name" => "Test",
"last name" => "Lead1",
"designation" => "call",
"email" => "",
"phone" => "958",
"fax" => "",
"mobile" => "",
"website" => "www.infosys.con",
"lead_source" => "Cold Call",
"lead_status" => "Contact in Future",
"industry" => "None",
"no_of_employees" => "45000",
"annual_revenue" => "0",
"rating" => "Active",
"smcreatorid" => "418176000000047003",
"created_by" => "Amit Patil",
"modifiedby" => "418176000000047003",
"modified_by" => "Amit Patil",
"created_time" => "2012-04-05 19:58:00",
"modified_time" => "2012-05-02 08:51:08",
"street" => "",
"city" => "",
"state" => "",
"zip_code" => "0",
"country" => "",
"description" => "",
"skype_id" => "",
"email_opt_out" => "false",
"salutation" => "Mr.",
"secondary_email" => ""
);
$arr3 = array("lead owner" => "Amit Patil");
$arr4 = array("lead owner" => "Amit aaa");
print_r(array_diff($arr1,$arr2));
echo "<br>";
print_r(array_diff($arr3,$arr4));
?>
Output is as below
Array ( [company] => SAM )
Array ( [lead owner] => Amit Patil )
If you want to diff between associative arrays so that the key-value pairs matter, not just the values, use array_diff_assoc, not array_diff.
You are understanding it wrongly.
The documentation page of array_diff says
Returns an array containing all the entries from array1 that are not
present in any of the other arrays.
But the Amit Patil is present in the second array hence it is returning only one value which is SAM and It is only one value which is not present in second array.
array_diff() returns complementary values. So you can do it like this:
array_diff(array_merge($arr1, $arr2), array_intersect($arr1, $arr2));
This way it will work.
It happens because the "array_diff" function returns the values that occurs for any key in the first array and do not occurs for none of the keys in the second array.
The lead_owner "Amit Patil" is not equal to the second array lead_owner, but is equal to the created_by and modified_by keys of the second one.
You should use "array_diff_assoc" for this purpose.
try this and see, this should work
print_r(array_diff_assoc($arr1,$arr2));
echo "<br>";
print_r(array_diff_assoc($arr3,$arr4));

Categories