I have tried array_merge and array_unique but it couldn't helped me out.
Here is my code:
public function syncContacts() {
$data['data'] = $this->main_manager->select_all('users'); # get all user data
$info[0] = [
"contact_name" => "a",
"number" => "031651651"
];
$info[1] = [
"contact_name" => "b",
"number" => "+923402382972"
];
$info[2] = [
"contact_name" => "c",
"number" => "31651651"
];
$info[3] = [
"contact_name" => "d",
"number" => "6165165123323"
];
$info[4] = [
"contact_name" => "e",
"number" => "316516512113"
];
for ($i = 0; $i < count($info); $i++) { # info array loop
if (substr($info[$i]['number'], 0, 1) == "+") { # finds + sign in numbers
for ($x = 0; $x < count($data['data']); $x++) { # user data array loop
if (
$info[$i]['number'] == $data['data'][$x]['country_code'] . $data['data'][$x]['phone_number'] # first condition
|| $info[$i]['number'] == $data['data'][$x]['country_code'] . 0 . $data['data'][$x]['phone_number'] # second condition
) {
$finalData['data']['registered'][$i]['name'] = $info[$i]['contact_name'];
$finalData['data']['registered'][$i]['number'] = $info[$i]['number'];
} else {
$finalData['data']['unregistered'][$i]['name'] = $info[$i]['contact_name'];
$finalData['data']['unregistered'][$i]['number'] = $info[$i]['number'];
$result = array_unique(array_merge($finalData['data']['unregistered'][$i], $info[$i]));
//
}
} # end of user data array loop
} else { # finds 0 in numbers
for ($x = 0; $x < count($data['data']); $x++) { # user data array loop
if (
$info[$i]['number'] == $data['data'][$x]['phone_number'] # first condition
|| 0 . $info[$i]['number'] == $data['data'][$x]['phone_number'] # second condition
|| $info[$i]['number'] == 0 . $data['data'][$x]['phone_number'] # third condition
) {
$finalData['data']['registered'][$i]['name'] = $info[$i]['contact_name'];
$finalData['data']['registered'][$i]['number'] = $info[$i]['number'];
} else {
$finalData['data']['unregistered'][$i]['name'] = $info[$i]['contact_name'];
$finalData['data']['unregistered'][$i]['number'] = $info[$i]['number'];
$result = array_unique(array_merge($finalData['data']['unregistered'][$i], $info[$i]));
// $result = array_merge($finalData['data']['unregistered'][$i], $info[$i]);
// $finalData['data']['unregistered'][$i] = array_unique($result);
}
} # end of user data array loop
}
} #end of info array loop
print_r($finalData);
die();
}
I am making a sync contacts webservice.
In $data array I am getting data from users table and I have 8 record in it.
3 record matched from my given array which is $info and two are unmatched. I made an array which is $finalData['data'].
I have to separate the record in registered and unregistered key of $finalData array. I have separated matched numbers in registered key of an array but couldn't separate the correct unmatched numbers in unregistered key of the array.
I am getting this result:
Array
(
[data] => Array
(
[unregistered] => Array
(
[0] => Array
(
[name] => a
[number] => 031651651
)
[1] => Array
(
[name] => b
[number] => +923402382972
)
[2] => Array
(
[name] => c
[number] => 31651651
)
[3] => Array
(
[name] => d
[number] => 6165165123323
)
[4] => Array
(
[name] => e
[number] => 316516512113
)
)
[registered] => Array
(
[0] => Array
(
[name] => a
[number] => 031651651
)
[1] => Array
(
[name] => b
[number] => +923402382972
)
[2] => Array
(
[name] => c
[number] => 31651651
)
)
)
)
Match index of first array with another and unset the matched index and then you will get the unregistered numbers.
How about using a hash like array? See example here http://php.net/manual/en/language.types.array.php
Related
I'm having a peculiar issue. I have a CSV file that has Comma Separated Values that I need to upload and then get Nested Array of values based on following 3 conditions;
The array will first loop through all values and get first 4 unique
characters. (Codes)
Match each column values with the with number of
columns in each row and give count of rows that matches 4 digit
codes. (Single_Devices for single column and Dual, Triple and Quad for respective columns count)
Match each column values with code and list all the
columns under the Devices. (Numbers)
CSV file
123429000000000
123429000000001
123429000000010,123429000000011
123429000000040,123429000000041
What I desire is;
Array
(
[Code] => 1234
(
[single_devices] => 2
(
[0] => Array
(
[0] => 123429000000000
)
[1] => Array
(
[0] => 123429000000001
)
)
[dual_devices] => 2
(
[0] => Array
(
[0] => 123429000000010
[1] => 123429000000011
)
[1] => Array
(
[0] => 123429000000040
[1] => 123429000000041
)
)
)
)
Is it possible?
I can manage JSON converted data or object or just associative nested array.
Edit: This is the code I wrote for which was only showing values and not indexes as I desired.
// Get all numbers in array
for ($j = 0; $j < count($csv_file[$i]); $j++){
$numbers[] = $csv_file[$i][$j];
}
// Get codes from numbers
for ($i = 0; $i < count($csv_file); $i++){
for ($j = 0; $j < count($csv_file[$i]); $j++){
$codes[] = substr($csv_file[$i][$j], 0, 4);
}
}
// Get unique codes from codes array
$codes = array_unique($codes);
// Get numbers and sort them codes and device count wise.
for ($i = 0; $i < count($csv_file); $i++){
for ($j = 0; $j < count($csv_file[$i]); $j++){
$q = count($csv_file[$i]); // set device count based on column count
if (count($csv_file[$i]) == $q){ // if device count is equal to column count
foreach ($codes as $code){ // loop through unique codes
if ($code == substr($csv_file[$i][$j], 0, 4)){ // if number's first 4 char matches code
// create array with code and then device count and add numbers
$devices[$code][$q.'_device_numbers'][$i][$j] = preg_replace('/\s+/', '', $csv_file[$i][$j]);
}
}
}
}
}
This is what I am getting from the above code.
Array
(
[1234] => Array
(
[1_sim_imeis] => Array
(
[0] => Array
(
[0] => 123429000000000
)
[1] => Array
(
[0] => 123429000000001
)
)
[2_sim_imeis] => Array
(
[2] => Array
(
[0] => 123429000000010
[1] => 123429000000011
)
[3] => Array
(
[0] => 123429000000040
[1] => 123429000000041
)
)
)
)
This is based on reading the file as a csv (using fgetcsv()) and extracting the first 4 digits of the first value on each line. It then uses another array to give the key for the 'single_devices' etc. key - using the count of the number of elements on the line (-1 as the array is 0 based)...
$fileName = "a.dat";
$output = [];
$baseData = [ 'single_devices', 'dual_devices', 'triple_devices', 'quad_devices' ];
$fh = fopen ( $fileName, "r" );
while ( ($data = fgetcsv($fh)) !== false ) {
$code = substr($data[0], 0, 4);
$output[$code][$baseData[count($data)-1]][] = $data;
}
fclose($fh);
print_r($output);
which with the test data gives...
Array
(
[1234] => Array
(
[single_devices] => Array
(
[0] => Array
(
[0] => 123429000000000
)
[1] => Array
(
[0] => 123429000000001
)
)
[dual_devices] => Array
(
[0] => Array
(
[0] => 123429000000010
[1] => 123429000000011
)
[1] => Array
(
[0] => 123429000000040
[1] => 123429000000041
)
)
)
With
while ( ($data = fgetcsv($fh)) !== false ) {
$code = substr($data[0], 0, 4);
if ( !isset($output[$code])) {
$output[$code] = ["code" => $code];
}
$deviceLabel = $baseData[count($data)-1];
$output[$code][$deviceLabel]['count'] =
($output[$code][$deviceLabel]['count'] ?? 0) + 1;
$output[$code][$deviceLabel][] = $data;
}
you can get an output of...
Array
(
[1234] => Array
(
[code] => 1234
[single_devices] => Array
(
[count] => 2
[0] => Array
(
[0] => 123429000000000
)
[1] => Array
(
[0] => 123429000000001
)
)
I've a series of arrays with values that goes from 1 to 5. Almost every array has missing values, some even dont have any values. My objective is to fill the missing values with 0. All those arrays are stored into a multidimensional array.
My array looks like:
Array
(
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[2] => Array
(
[0] => 1
[1] => 5
)
[3] => Array
(
[0] => (this array has no values)
)
[4] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
etc...
)
How it should be:
Array
(
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 0
[4] => 0
)
[2] => Array
(
[0] => 1
[1] => 0
[2] => 0
[3] => 0
[4] => 5
)
[3] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
)
[4] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
etc...
)
Any help would be appriciated!
For each of your subarrays loop through the numbers 1 to 5, and if that value exists set its key to be one less than its value:
$newarray = array();
foreach($arr as $key => $subarr) {
for ($i = 1; $i <= 5; $i++) {
if (in_array($i, $subarr)) $newarray[$key][$i - 1] = $i;
else $newarray[$key][$i - 1] = 0;
}
}
Where $newarray is your output and $arr is your input array.
You may want to note that PHP does not truly do multidimensional arrays. It only allows you to relate 2 flat arrays together which is not true multidimensionality.
This does not work and will produce results described above.
$menu[1] = "My Training"; //not $menu[1][0]
$menu[1][1] = "To Do List";
$menu[1][2] = "Catalog";
$menu[1][3] = "Self-Report";
$menu[1][4] = "Completions";
$menu[2] = "Manager";
$menu[2][1] = "Direct Reports";
$menu[2][2] = "Incompletes";
$menu[2][3] = "Completions";
$menu[3] = "Instructor";
$menu[3][1] = "My Classes";
$menu[3][2] = "Printables";
$menu[3][3] = "Qualifications";
This does work.
$menu[1] = "My Training"; //not $menu[1][0]
$submenu[1][1] = "To Do List";
$submenu[1][2] = "Catalog";
$submenu[1][3] = "Self-Report";
$submenu[1][4] = "Completions";
$menu[2] = "Manager";
$submenu[2][1] = "Direct Reports";
$submenu[2][2] = "Incompletes";
$submenu[2][3] = "Completions";
$menu[3] = "Instructor";
$submenu[3][1] = "My Classes";
$submenu[3][2] = "Printables";
$submenu[3][3] = "Qualifications";
$submenu is only related to $menu through the first key number as there are no first dimension values to $submenu.
Something like this (array_pad() won't do the trick). $myArray is your source array. Completed array is returned in $result:
$result = array();
foreach( $myArray as $subKey=>$subArray ) {
for( $i=0; $i<5; $i++ ) {
if( isset( $subArray[$i] )) {
$result[$subKey][$i] = $subArray[$i];
} else {
$result[$subKey][$i] = 0;
}
}
}
Note, we do copy of the array. You cannot fill array in-place.
It's been many years since I wrote any PHP but something like this might do the trick I guess?
for($i = 0; $i < 5; $i++)
{
if(empty($myArray[$i])
{
$myArray[$i] = 0;
}
}
I have a single multidimensional array that I'm trying to merge keys. I'd like to merge where identical keys occur on a separate key from the one I'm trying to merge.
My current array looks like so.
Array
(
[0] => Array
(
[zone_id] => 2
[zone_title] => Users
[link_title] => Users
)
[1] => Array
(
[zone_id] => 2
[zone_title] => Users
[link_title] => Add User
)
[2] => Array
(
[zone_id] => 3
[zone_title] => Locations
[link_title] =>
)
)
I would like to leave the array as is with the exception of merging together arrays that have identical zone_id keys.
Result
Array
(
[0] => Array
(
[zone_id] => 2
[zone_title] => Users
[link_title] => Array
(
[0] => Users
[1] => Add user
)
)
[1] => Array
(
[zone_id] => 3
[zone_title] => Locations
[link_title] =>
)
)
<?php
function merge_keys($arr){
for ($key = 0; $key < count($arr); $key++) {
$zone_id = $arr[$key]['zone_id'];
$index = search($arr, $zone_id);
if ($index != $key && $index != -1){
$link_title = $arr[$key]['link_title'];
$link_title2 = $arr[$index]['link_title'];
$arr[$key]['zone_id'] = $zone_id;
$arr[$key]['zone_title'] = $arr[$key]['zone_title'];
$arr[$key]['link_title'] = array($link_title, $link_title2);
unset($arr[$index]);
}
}
return $arr;
}
function search($arr, $zone_id){
for ($i = count($arr) - 1; $i >= 0 ; $i--) {
$item = $arr[$i];
$tmp_zone_id = $item['zone_id'];
if($tmp_zone_id == $zone_id){
return $i;
}
}
return -1;
}
$arr = array(array('zone_id' => 2, 'zone_title' => 'Users', 'link_title' => 'Users'),
array('zone_id' => 2, 'zone_title' => 'Users', 'link_title' => 'Add User'),
array('zone_id' => 3, 'zone_title' => 'Locations', 'link_title' => ''));
echo "Before change: \n";
print_r($arr);
$arr = merge_keys($arr);
echo "After change: \n\n";
print_r($arr);
?>
I'm trying to process an uploaded CSV file into an array in PHP. I have that working fine, but some files from users end up have a bunch of blank rows with delimiters. This usually happens when they use Excel on an existing file. Highlighting the old cells and just clearing them.
Sample CSV File
lineNo,date,vendor,amount
1,5/2/2012,V000236,3727.21
2,5/2/2012,V003432,4826.19
,,,
,,,
Becomes the following array
Array
(
[0] => Array
(
[0] => lineNo
[1] => date
[2] => vendor
[3] => amount
)
[1] => Array
(
[0] => 1
[1] => 5/2/2012
[2] => V000236
[3] => 3727.21
)
[2] => Array
(
[0] => 2
[1] => 5/2/2012
[2] => V003432
[3] => 4826.19
)
[3] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
)
[4] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
)
)
I don't want to just remove any blank rows, I want to stop after array index 2. Go easy on my function I'm new :P
function csvToArray($csvFile, $specialChars = FALSE) {
$arrayCSV = array();
if (($csvHandle = fopen($csvFile, "r")) !== FALSE) { // Open the CSV
$csvKey = 0; // Set the parent array key to 0
while (($csvData = fgetcsv($csvHandle)) !== FALSE) {
$c = count($csvData); // Count the total keys in each row
//need something to stop on blank delimiter rows ,,,
for ($x = 0; $x < $c; $x++) { //Populate the array
if ($specialChars === TRUE) {
$arrayCSV[$csvKey][$x] = htmlspecialchars($csvData[$x]);
} else {
$arrayCSV[$csvKey][$x] = $csvData[$x];
}
}
$csvKey++;
}
fclose($csvHandle);
}
return $arrayCSV;
}
Ultimately, I'd like this returned
Array
(
[0] => Array
(
[0] => lineNo
[1] => date
[2] => vendor
[3] => amount
)
[1] => Array
(
[0] => 1
[1] => 5/2/2012
[2] => V000236
[3] => 3727.21
)
[2] => Array
(
[0] => 2
[1] => 5/2/2012
[2] => V003432
[3] => 4826.19
)
)
Can't you break; your while loop as soon as you find an empty value?
if (($csvHandle = fopen($csvFile, "r")) !== FALSE) { // Open the CSV
$csvKey = 0; // Set the parent array key to 0
while (($csvData = fgetcsv($csvHandle)) !== FALSE) {
$c = count($csvData); // Count the total keys in each row
// ## Flag variable ##########
$empty = true;
for ($x = 0; $x < $c; $x++) { //Populate the array
// ## Test each value ##########
$empty = $empty && (empty($csvData[$x]));
if ($specialChars === TRUE) {
$arrayCSV[$csvKey][$x] = htmlspecialchars($csvData[$x]);
} else {
$arrayCSV[$csvKey][$x] = $csvData[$x];
}
}
// ## Stop loop if all empty ##########
if ($empty) {
unset($arrayCSV[$csvKey]);
break;
}
$csvKey++;
}
fclose($csvHandle);
}
Note:
A blank line in a CSV file will be returned as an array comprising a single null field, and will not be treated as an error.
if ($c == 1 && current($csvData) === null) {
break;
}
You can run a extra loop for checking empty
while(! feof($file)){
$current_data = fgetcsv($file);
for ($i=0; $i < $total_title ; $i++) {
if( empty( $current_data[ $i ] ) ){
unset($information[$itt]);
break;
}
$information[$itt][ $titles[$i] ] = $current_data[$i] ;
}
$itt = $itt+1;
}
I recommend this php function that does exactly what you want
http://www.php.net/manual/es/function.file.php
i have an array like:
Array ( [0] => #!A1#DC [1] => #IMSR102.71/74.82 [2] => #HV50 [3] => #PR7/7/ [4] => #RX0 [5] => #ERN/1//0 [6] => #Q2 [7] => #!A1#DC [8] => #IMSR102.50/74.82 [9] => #HV40 [10] => #PR5/5/ [11] => #RX0 [12] => #ERN/1//1 [13] => #Q2 etc etc with hundreds o values
i get this array from a file (with the function file($filename) ) and i need to split it in many subarray.
"!A1#DC" this is the beginning of a series of values that ends with #Q2 but the number of the values between the beginning and the end is not always the same and the only 2 values that are same are the two given ("!A1#DC" for the beginning and "#Q2" for the end)
how can i get somethings like this?
Array (
[0] => Array ( [0] => #!A1#DC [1] => #IMSR102.71/74.82 [2] => #HV50 [3] => #PR7/7/ [4] => #RX0 [5] => #ERN/1//0 [6] => #Q2 )
[1] => Array (
[1] => #!A1#DC [2] => #IMSR102.50/74.82 [3] => #HV40 [4] => #PR5/5/ [5] => #RX0 [6] => #ERN/1//1 [7] => #Q2 etc etc
could you please help me?
thanks
Loop through an array. When you meet starting value, store it's index. When you meet ending value, use array_slice() to extract the part between the last pair of starting and ending values, store this part into another array.
$source = array (
'#!A1#DC',
'#IMSR102.71/74.82',
'#HV50',
'#PR7/7/',
'#RX0',
'#ERN/1//0',
'#Q2',
'#!A1#DC',
'#IMSR102.50/74.82',
'#HV40',
'#PR5/5/',
'#RX0',
'#ERN/1//1',
'#Q2',
);
$dest = array();
$startValue = '#!A1#DC';
$endValue = '#Q2';
$startIndex = 0;
foreach ( $source as $index => $value ) {
if ( $value === $startValue ) {
$startIndex = $index;
} else
if ( $value === $endValue ) {
$dest[] = array_slice($source, $startIndex, $index - $startIndex + 1);
}
}
print_r($dest);
Basically you need to loop through each element of $input, collecting those within START and END elements into a separate array:
$input = array("#!A1#DC", "A", "B", "#Q2");
$values = array();
$current = 0;
define("START", "#!A1#DC");
define("END", "#Q2");
for ($i = 0; $i < count($input); $i++) {
if ($input[$i] == END) {
// Ignore any elements after this point until we see START
$current = null;
} else if ($input[$i] == START) {
// Create a new current collection array
$current = count($values);
$values[$current] = array();
} else {
// Store the value if we are collecting
if ($current !== null) {
$values[$current][] = $input[$i];
}
}
}