What's wrong with this simple code? - php

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));

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

How to delete a nested array inside of an array

I have an multidimensional array made out of form data that can look like this example:
array [
"absender" => "Maxim Ivan",
"email" => "maximivan#example.com",
"telefon" => "1234567890",
"fax" => null,
"grund" => "Gehaltserhöhung",
"termin" => [
0 => [
"person" => "Some Name",
"meeting" => "10.05"
],
1 => [
"person" => "Another Name",
"meeting" => "18.05"
],
2 => [
"person" => "Again another name",
"meeting" => null,
"next-possible-meeting" => "1"
],
3 => [
"person" => "And again",
"meeting" => null,
"next-possible-meeting" => "1"
],
4 => [
"meeting" => null,
],
"bemerkung" => "some notes by Maxim"
]
'person' and 'next-possible-meeting' are checkboxes while 'meeting' is a textarea. I only need the 'termin'-data when 'person' exists, so I store each of them in different arrays (one for persons, one for meetings and one for next-possible-meetings).
That means I don't need the array to be nested anymore, the 'termin' can (and should) be deleted out of it. But I don't know how to access the nested array correctly.
How do I delete the whole 'termin'-array out of the whole array and therefore make it a normal and not a multidimensional array?
Use unset()
if(isset($array['termin'])){
unset ($array['termin']);
}
Output:- https://3v4l.org/1Yj4F
Note:- isset() used to check that index exist or not, if not function call will saved.

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

Compare two arrays (Stock inventory)

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;
}
}

Construct a new array out of an existing array in PHP

I have an $accounts array with this data in it
array:2 [▼
0 => array:25 [▼
"email_address" => "bob#xyzcorp.com"
"account_id" => 111
"password" => "abc"
"account_type" => "admin"
"name_prefix" => "Mr"
"first_name" => "Bob"
"middle_names" => "X."
"last_name" => "Jones"
"name_suffix" => "Jr."
"non_person_name" => false
"DBA" => ""
"display_name" => "BobJ"
"address1" => "111 Park Ave"
"address2" => "Floor 4"
"address3" => "Suite 4011"
"city" => "New York"
"state" => "NY"
"postal_code" => "10022"
"nation_code" => "USA"
"phone1" => "212-555-1212"
"phone2" => ""
"phone3" => ""
"time_zone_offset_from_utc" => -5
"customer_type" => 2
"last_updated_utc_in_secs" => 200200300
]
1 => array:25 [▼
"email_address" => "tom#xyzcorp.com"
"account_id" => 112
"password" => "abd"
"account_type" => "mbn"
"name_prefix" => "Mr"
"first_name" => "Tom"
"middle_names" => "Z."
"last_name" => "Smith"
"name_suffix" => "Sr."
"non_person_name" => false
"DBA" => ""
"display_name" => "TomS"
"address1" => "112 Park Ave"
"address2" => "Floor 3"
"address3" => "Suite 3011"
"city" => "New York"
"state" => "NY"
"postal_code" => "10022"
"nation_code" => "USA"
"phone1" => "212-555-2323"
"phone2" => ""
"phone3" => ""
"time_zone_offset_from_utc" => -5
"customer_type" => 2
"last_updated_utc_in_secs" => 200200300
]
]
I want to construct a new array out of this array.
But the new array I only want to have 2 keys: email_address and the password.
I've tried:
$new_array = array();
$i = 0;
foreach ($accounts as $account) {
$new_array[$i++];
foreach ($account as $user) {
$new_array['email_address'] = $user['email_address'];
$new_array['password'] = $user['password'];
}
}
dd($new_array);
I hope someone can give me a little push here.
You're not adding new elements to $new_array. Each time through the foreach loop you overwrite the same two keys. The elements of $new_array should be arrays.
You also don't need the inner loop, because each account is just one user.
foreach ($accounts as $account) {
$new_array[] = array('email_address' => $account['email_address'],
'password' => $account['password']);
}
You don't need the variable $i, because $new_array[] = pushes a new element onto the array.
$new_array[$i++];
foreach ($account as $user) {
$new_array['email_address'] = $user['email_address'];
$new_array['password'] = $user['password'];
}
Your issue is here, you almost have it, but as you are using the array within the array, with the two sets of foreach loops, you thus need to have the same depth of structure if you want to preserve more than one records' password and email_address.
So, replace the above quote with:
$i++
$new_array[$i];
foreach ($account as $user) {
$new_array[$i]['email_address'] = $user['email_address'];
$new_array[$i]['password'] = $user['password'];
}
This will output
$new_array(
[0] ===> ['password'] --> {data}
===> ['email_address'] --> {data}
[1] ===> ['password'] --> {data}
===> ['email_address'] --> {data}
....
)
Edit:
This can further be reduced and tidied up as:
$i++
$new_array[$i];
$new_array[$i]['email_address'] = $account['email_address'];
$new_array[$i]['password'] = $account['password'];
Because you know the key of the value you want so you don't need to break the outer array apart to find anything, you can get it by direct reference to outerValue (account) and then key(email_address, etc).

Categories