Compare Arrays with array_diff - but only first chars - php

I got following situation.
I got a csv file and some data in a mysql database.
I want to load the csv file and compare it to a row in the mysql database.
The csv file got following types of data:
eet003 240
eet003 180
eet003 280
eet299 100
But in the database the data looks like this:
eet003
eet299
So both datas a stored in arrays.
$array1
$array2
And I want to compare the two arrays and save the result in a third array.
$diff = array_diff($array1, $array2)
But I onlny want to compare the first 6 chars of the data. So right now eet003 240 is different from eet003. But for me its the same. I only need eet003 e.g.
How could I archieve that? I now the substr function but array1 is created the follwing way:
$rows = array(); //aray for csv file
$rows = file('pinesite_eet.csv', FILE_IGNORE_NEW_LINES); //write csv in array
I don't know how du cut the string from the csv when it's loaded in the array.
The second array is written from a mysql_query.
Any suggestions on how I could do that?

I think something like this should work:
(Here I just use array_udiff() with a anonymous function where I only use the first part of the file data and compare it with the database data)
<?php
$result = array_udiff($fileData, $dbData, function($a, $b) {
if(strcasecmp(explode(" ", $a)[0], $b) == 0)
return 0;
return strcasecmp(explode(" ", $a)[0], $b);
});
?>

Might be easier to just modify the data. This removes the space and everything after in each element:
$rows = preg_replace('/ .*/', '', $rows);
Then array_diff() should work as expected.

Related

Read consecutive lines from file into key => value array

I am trying to convert a user/pass txt file to an array, I tried to do this with a foreach, explode, reg_split, but didn't get anything working in the right way.
Also a blank line should be skipped...
Example text file:
username1
password1
username2
password2
username3
password4
Example array:
array(
$username1 => $password1,
$username2 => $password2
)
Create an array of pairs from the consecutive lines, then combine the column of keys with the column of values:
$chunks = array_chunk(
file('userpass.txt', FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES),
2
);
$users = array_combine(
array_column($chunks, 0),
array_column($chunks, 1)
);
Explanation
$chunks is an array of arrays: each inner array has two elements: #0 is the username (first line) and #1 is the password (second line). Using file to skip blank lines and remove trailing new-lines keeps this code simple, but not bullet-proof.
$users then is made by taking all the usernames (index 0 from all the inner arrays) and pointing them to all the passwords (index 1).
You can accomplish the same with a loop over $chunks. However, I prefer this approach because all looping is handled inside the engine, where it is marginally more performant.
Split the file into one array and then combine them into a new array with key-value pairs
$file = file("usernames.txt", FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES);
$array = [];
for($i = 0; $i < count($file) - 1; $i++){
$array[$file[$i]] = $file[$i + 1];
}
I have to think on it, but I know you can read the file into an array using php's file() method.
$var = file("myFile.txt", FILE_SKIP_EMPTY_LINES);

PHP - Comparing an array with a multidimensional array?

I have two arrays, one of them is a one dimensional array, a product of an explode by \n and then exploded by comma on a csv file, the other array is a mysql_fetch_array that contains information from the database, my goal is to compare those arrays and find out the difference between them or new records that exist in the csv array and not in the database, i have tried array_diff, array_diff_assoc, array_udiff , i tried comparing each line of the csv file to the database using a select statement but its taking forever to load, i tried almost all the solutions here on stackoverflow.com, but i can't seem to compare those arrays.
This is a snippet from my code :
$input = file_get_contents('test.csv');
$newarray = explode("\n", $input);
$sql = mysql_query("SELECT * FROM products")or(die(mysql_error()));
$basearray = mysql_fetch_array($sql);
foreach ($newarray as $key => $value) {
$each_line = explode(",", $value);
// code goes here
// i tried producing a new array here and compare it
// to $basearray later, but it didn't work.
}

Converting multiple strings into JSON arrays

I have multiple strings that looks like the following: 11-16, 16-12, 14-16
I will have multiple of these, and I need to store them in JSON. I need to store it in the following format:
[
{
"score_1": 11,
"score_2": 16
},
{
"score_1": 16,
"score_2": 12
},
{
"score_1": 14,
"score_2": 16
}
]
with score_1 being the first number, and score_2 being the second number. How will I be able to do this in PHP?
Thanks
First create an array. Next create an object, then explode the string on the hyphen and store the intval'd first and second number in the object. Push that object into your array. Repeat for as many strings as you have. Finally, use json_encode to get a JSON-encoded string.
$arr = [];
function addString($str, &$arr) {
$str = explode("-", $str);
$obj = new stdClass();
$obj->score_1 = intval($str[0]);
$obj->score_2 = intval($str[1]);
$arr[] = $obj;
}
addString("11-16", $arr);
addString("16-12", $arr);
echo json_encode($arr);
Output:
[{"score_1":11,"score_2":16},{"score_1":16,"score_2":12}]
Edit: Updated the above code to use intval as the OP has integers in his object in the expected output.
Two steps:
Convert the strings to the according data structure (e.g. array of stdClass objects).
Convert that data structure to JSON.
Note: Since you already know the output you want, you could parse that output to get an idea how its representation in PHP would look like, as a suggestion for the results of the first step.

Output only csv lines if column increment is 2

I have a csv file that I would like to filter. The output I need would be only to output the lines if the increment is not equal to 2. In the csv file below, I would like to compare the first line with the second line, if the increment is 2, check line 3 vs line 2, and so on. If the increment is not equal to 2, output the line. I'm looking at the 3rd cloumn values
L1,is,2.0,mins,LATE,for,Arrive,at,shop,18:07:46
L1,is,4.0,mins,LATE,for,Arrive,at,shop,18:09:46
L1,is,6.0,mins,LATE,for,Arrive,at,shop,18:11:46
L1,is,8.0,mins,LATE,for,Arrive,at,shop,18:13:46
L1,is,10.0,mins,LATE,for,Arrive,at,shop,18:15:46
L1,is,2.0,mins,LATE,for,Arrive,at,shop,18:19:49
L1,is,4.0,mins,LATE,for,Arrive,at,shop,18:21:49
L1,is,6.0,mins,LATE,for,Arrive,at,shop,18:23:49
L1,is,8.0,mins,LATE,for,Arrive,at,shop,18:25:49
L1,is,10.0,mins,LATE,for,Arrive,at,shop,18:27:49
L1,is,16.2,mins,LATE,for,Arrive,at,shop,18:34:02
L1,is,18.2,mins,LATE,for,Arrive,at,shop,18:36:02
L1,is,20.2,mins,LATE,for,Arrive,at,shop,18:38:02
L1,is,2.0,mins,LATE,for,Arrive,at,bridge,21:45:26
L1,is,4.0,mins,LATE,for,Arrive,at,bridge,21:47:26
L1,is,6.0,mins,LATE,for,Arrive,at,bridge,21:49:26
So only lines 5,10,13 and 16 would output to page.
I'm stuck on this and would appreciate any help or direction on where to look.
Thanks
If your file is not too big, you can load it into memory directly, like this:
$data = array_map(function($row)
{
return explode(',', $row);
}, file('/path/to/file.csv', FILE_IGNORE_NEW_LINES));
$result = [];
$increment = 2;
$delta = 1E-13;
for($i=1; $i<count($data); $i++)
{
if(abs($data[$i][2]-$data[$i-1][2]-$increment)>$delta)
{
$result[$i] = $data[$i];
}
}
-since your column holds floats, safe comparison on equality will be using precision delta.
Your data will be gathered in $result array, so you can output it like
foreach($result as $row)
{
echo(join(',', $row).PHP_EOL);
}
-or, else, do not store rows inside $result array (if you will need them no longer) and use first cycle to output your rows.
Edit:
Sample above will work in PHP>=5.4 For PHP 5.3 you should replace array definition to
$result = array();
and if you have even older PHP version, like 5.2, then callback inside array_map() should be rewritten with using create_function()

Get data from a string and return it as JSON in PHP

NOTE : This is for a PHP script !
So I've been working on a program but I right now I am stuck because I can't split the data right.
I have a list with numbers just like this :
50.0.1 581 50.0.2 545 50.0.3 541 50.0.4 18 50.0.5 2 50.0.6 33 50.0.7 1 [...]
I have add that information into an ARRAY or JSON format (preferable JSON).
The main data looks like this (we take groups): 50.0.1 581 so basically I have to split 50.0.1 from 581 add it to JSON/ARRAY and then move to the next group that in our case is 50.0.2 545. (and so on)
Example JSON:
{"result": {
"50.0.1": "581",
"50.0.2": "545"
}}
Note : First value will always have the same format : [0-9]{2}.[0-9].[0-9] (ex : 50.0.1)
However, the second value can be 1 to 4 digit long : [0-9]{1,4}.
I am sorry if I did not make myself clear - it is quite hard to explain. Will add more example if required !
Thank you very much !
simply explode on the spaces, e.g.
$arr = explode(' ', $your_string);
then build a new array using each pair of elements:
$newarr = array();
for ($i = 0; $i < count($arr); $i += 2) { // note the += 2
$newarr[$arr[$i]] = $arr[$i+1];
}
echo json_encode($newarr);
note that this will probably trash things if any of those "key" values are duplicates.
My own working solution : /([.\d])\t(\d)/ . Will output 3 arrays. Simple combine second with third and I got what I want.
Another way is to use array_chunk() after explode(), and then access values in JS as item[0] and item[1] for each pair.

Categories