Multidimensional array remove duplicates from columns and rows - php

I have to insert some data from an excel document into the database.
The data has been saved as .csv and then added into an array through PHP.
The data look like:
Column A Column B Column C
100 200 100
50 10 100
200 200 100
30 10 300
Then I use this to separate each columns (within a foreach loop)
list( $columnA, $columnB) = explode( ',', $values[0] );
$columnA= array($columnA);
print_r($columnA);
The above code prints the values of each column.
So I'm trying to find a way to remove duplicates from each column and then from each row (no matter what the column name is). I want to remove duplicates from the whole document. For the data I posted for example I just need the values 100,200,50,10,30,300 (only the unique values from the whole doc).
UPDATE:
What the original array (the one I've created by using for loop and passing all data from .CSV file) shows:
Array ( [0] => G2100,100%,,,,,,,,,200,0.24,77,51,2,47, )
Array ( [0] => G2101,100%,,,,,,,,,200,0.24,77,42,15,43, )
Array ( [0] => G2102,30%,,,,,,,,,200,0.24,77,38,25,37, )
So by using the list function I mentioned before I split all columns and get the values for each column. THEN if i print $columnB array for example it shows this:
Array ( [0] => 100%) Array ( [0] => 100%) Array ( [0] => 30%)
and so on. When I use unique_array it does nothing.
$columnB = array_unique($columnB, SORT_REGULAR);
I tried to use array_map but it doesn't work either.
Any help would be much appreciated.

I don't understand why does array_unique not works in your case, because actually it solves the problem:
<?php
$columnA = array(50,50,200,10);
$columnB = array(100,50,200,100);
$columnC = array(150,50,250);
$merged = array_merge($columnA, $columnB, $columnC);
$result = array_unique($merged);
var_dump($result);
?>
And output is:
array(6) {
[0]=>
int(50)
[2]=>
int(200)
[3]=>
int(10)
[4]=>
int(100)
[8]=>
int(150)
[10]=>
int(250)
}
This is an trivial example, but if you can manage that your inputs are like arrays above, then you can use array_unique to have only unique values...
EDIT 1:
To remove % sign from string just use rtrim where is needed:
$string = '100%';
$trimmed = (int)rtrim($string,'%');//make it int(or float if you like)
var_dump($trimmed);
EDIT 2:
Related to looping through arrays:
//I suppose this
//Array ( [0] => 100%) Array ( [0] => 100%) Array ( [0] => 30%)
//maps to this
$columnA = array(
0=>array('100%'),
1=>array('100%'),
2=>array('30%')
);
//go through every element
$temp = array();
foreach($columnA as $subArray){
//in this case when we know that there is only one element in the array we can do next:
$temp[] = $subArray[0];
}
$result = array_unique($temp);
echo "<pre>";
var_dump($result);
echo "</pre>";
And this would be the output:
array(2) {
[0]=>
string(4) "100%"
[2]=>
string(3) "30%"
}

Related

find, save and remove duplicate values from more then one array

first array
[0]=> Brian
[1]=> A
[2]=> Leo
[3]=> A
[4]=> Mike
second array
[0]=> 1
[1]=> 2
[2]=> 3
[3]=> 4
[4]=> 5
I want to check if in first array there are duplicates, if yes, save only the first occurrence of that value, the other removes, remember those keys, and delete them from the second array too. In the end i want to have
first array
[0]=> Brian
[1]=> A
[2]=> Leo
[3]=> Mike
second array
[0]=> 1
[1]=> 2
[2]=> 3
[3]=> 5
I tried with this but second array does not have duplicates so it won't work for both array:
array_values(array_unique($array));
You did
array_values(array_unique($array));
This will give unique values of $array, but you won't find which index of second array needs to be unset.
Approach #1:
Your best shot is a simple for loop with an isset check. If we find the value already present in our $set(a new temp array), we unset that index from both original arrays, else we preserve it.
Snippet:
<?php
$arr1 = [
'Brian',
'A',
'Leo',
'A',
'Mike'
];
$arr2 = [
1,2,3,4,5
];
$set = [];
foreach($arr1 as $key => $value){
if(!isset($set[$value])) $set[$value] = true;
else{
unset($arr1[$key]); // foreach creates a copy of $arr1, so safe to unset
unset($arr2[$key]);
}
}
print_r($arr1);
print_r($arr2);
Demo: https://3v4l.org/BQ9mA
Approach #2:
If you don't like for loops, you can use array wrappers to do this. You can use array_combine to make first array values as keys and second array values as arrays. Note that this would only preserve the latest key value pairs, so we do a array_reverse to only maintain first occurrence pairs.
Snippet:
<?php
$arr1 = [
'Brian',
'A',
'Leo',
'A',
'Mike'
];
$arr2 = [
1,2,3,4,5
];
$filtered_data = array_combine(array_reverse($arr1),array_reverse($arr2));
print_r(array_keys($filtered_data));
print_r(array_values($filtered_data));
Demo: https://3v4l.org/mlstg
This simply builds a temp array using the values from your 2 arrays.
Because we use values of $a1 as the key, dups get overwritten and therefore lost. The array_keys_exists() check makes sure the first Dup is used and not subsequent dups. Then we just split the array into the two input arrays.
$a1 = ['Brian', 'A', 'Leo', 'A', 'Mike'];
$a2 = [1,2,3,4,5];
#temp array created using values of $a1 as key so dups get dropped because they are reused
foreach ($a1 as $i=>$a) {
if ( ! array_key_exists($a, $new)){
$new[$a] = $a2[$i];
}
}
$a1 = array_keys($new);
$a2 = array_values($new);
print_r($a1);
print_r($a2);
RESULT:
Array
(
[0] => Brian
[1] => A
[2] => Leo
[3] => Mike
)
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 5
)
Please note that array_unique preserves keys so you can easily use it to filter the second array too:
$firstArray = array_unique($firstArray);
$secondArray = array_intersect_key($secondArray, $firstArray);
var_dump(array_values($firstArray), array_values($secondArray));
From the docs of array_unique:
Note that keys are preserved. If multiple elements compare equal under the given sort_flags, then the key and value of the first equal element will be retained.

How to save only numeric numbers from string into an array of int in PHP

in my POST variable i have: print_r($_POST["partecipanti"]);
It displays
["1", "2"]
I want to save only the numbers of the post variable in an int array. I tried
$array = array();
preg_match_all('/-?\d+(?:\.\d+)?+/', $_POST["partecipanti"], $array);
But print_r($array) returns
Array (
[0] => Array (
[0] => 1
[1] => 2
)
)
How can i have a variable like
Array (
[0] => 1
[1] => 2
)
Hope i explained good, thanks all in advance
preg_match_all returns a new multidimensional array every time. But you could just "pop" the array:
$array = array();
preg_match_all('/-?\d+(?:\.\d+)?+/', $_POST["partecipanti"], $array);
$array = $array[0];
Returns:
Array (
[0] => 1
[1] => 2
)
to filter integer values from an array, use array_filter
$arr = array_filter($_POST["participanti"], function($v) { return is_int($v); });
In case you want to convert the array values into integers:
$arr = array_map(function($v) { return (int)$v; }, $_POST["participanti"]);
In both cases the $arr contains only integer values.
Assuming $_POST["partecipanti"]) is a string because you use it directly in your example and the second parameter of preg_match_all is a string.
preg_match_all returns an array where the matches are in the first entry and contains array of strings. You could get that array by using $array[0] .
Besides 1 and 2, your regex -?\d+(?:\.\d+)?+ also matches for example -8.44 or 99999999999999999999999999.
If you want an array of int, you could use array_map with for example the function intval for the callback.
Note the maximum size of an int and the rounding of the values.
For example:
$str = "test 1, test 2, test 2.3 and -8.44 plus 99999999999999999999999999999999999999999999999999";
preg_match_all('/-?\d+(?:\.\d+)?/', $str, $array);
$array = array_map/**/("intval", $array[0]);
var_dump($array);
Demo
That results in:
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(2)
[3]=>
int(-8)
[4]=>
int(9223372036854775807)
}

How to get value in an object in PHP

I have a variable with object like this in PHP code.
[{"author_id":2},{"author_id":1}]
How to get the value of author_id. thanks
use json_decode to convert the object in php and get it. Example:
<?php
$xx='[{"author_id":2},{"author_id":1}]';
$arr=json_decode($xx,true);
print_r($arr);
//Output: Array ( [0] => Array ( [author_id] => 2 ) [1] => Array ( [author_id] => 1 ) )
echo $arr[0]["author_id"];
//Outpu: 2
?>
This is serialized JSON Array with JSON objects inside.
$str = '[{"author_id":2},{"author_id":1}]';
$arr = json_decode($str, true);
foreach($arr as $item) {
echo $item['author_id'];
}
That data you posted is in JSON format. After decoding that standard format you can directly access the contents.
For the first entry that would simply be:
<?php
$data = json_decode('[{"author_id":2},{"author_id":1}]');
var_dump($data[0]->author_id);
The output obviously is:
int(2)
To access all entries have a try like that:
The output then is:
array(2) {
[0]=>
int(2)
[1]=>
int(1)
}

How to combine an array with another array

I've two arrays array1 and array2 and I want to add all elements of array2 to the end of array1. array1 contains many items.
The keys are numeric and I don't want this syntax:
array1 = array1 + array2
or
array1 = SomeArrayFun(array1,array2)
As it takes away CPU times ( as array is created twice )
What I want is:
array1 . SomeAddFun(array2); // This will not create any new arrays
Is there any way to do it?
If you'd like to append data to an existing array you should se array_splice.
With the proper arguments you'll be able to insert/append the contents of $array2 into $array1, as in the below example.
$array1 = array (1,2,3);
$array2 = array (4,5,6);
array_splice ($array1, count ($array1), 0, $array2);
print_r ($array1);
output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
You might use ArrayObject with the append function:
$arrayobj = new ArrayObject(array('first','second','third'));
$arrayobj->append('fourth');
Result:
object(ArrayObject)#1 (5) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
[3]=>
string(6) "fourth"
}
Don't know for appending arrays though, as they seem to be appended as a "subarray" and not as part of the whole.
Docs: http://www.php.net/manual/en/arrayobject.append.php

PHP arrays - How to 1-dimensional array into nested multidimensional array?

When retrieving a hierarchical structure from MySQL (table with one ID column and one PARENT column signifying the hierarchical relationships), I map the result into an enumerated array as follows (for this example the numbers are arbitrary):
Array ( [3] => Array ( [7] => Array () ), [7] => Array ( [8] => Array () ) )
Notice 3 is the parent of 7, and 7 is the parent of 8 (this could go on and on; and any parent could have multiple children).
I wanted to shrink this array into a nested multidimensional array as follows:
Array ( [3] => Array ( [7] => Array ( [8] => Array () ) ) )
That is, each NEW id is automatically assigned an empty array. Regardless, any ID's children will be pushed into their parent's array.
Take a look at the following illustration for further clarification:
alt text http://img263.imageshack.us/img263/4986/array.gif
This will probably result in a complicated recursive operation, since I always have to check whether a parent with any certain ID already exists (and if so, push the value into its array).
Is there a built-in php function that can assist me with this? Do you have any idea as to how to go about constructing this? For what it's worth I'm using this to built a navigation bar in wordpress (which can contain categories, subcategories, posts... essentially anything).
The idea is that you keep an auxiliary array with all the nodes (parent and child) you find. The values of this arrays are references that back your result.
This builds the tree in linear time (array_key_exists does a hash table lookup, which is on average O(1)):
//table contains (id, parent)
$orig = array(
11 => 8,
7 => 3,
8 => 7,
99 => 8,
16 => 8,
);
$childrenTable = array();
$result = array();
foreach ($orig as $n => $p) {
//parent was not seen before, put on root
if (!array_key_exists($p, $childrenTable)) {
$childrenTable[$p] = array();
$result[$p] = &$childrenTable[$p];
}
//child was not seen before
if (!array_key_exists($n, $childrenTable)) {
$childrenTable[$n] = array();
}
//root node has a parent after all, relocate
if (array_key_exists($n, $result)) {
unset($result[$n]);
}
$childrenTable[$p][$n] = &$childrenTable[$n];
}
unset($childrenTable);
var_dump($result);
gives
array(1) {
[3]=>
array(1) {
[7]=>
array(1) {
[8]=>
array(3) {
[11]=>
array(0) {
}
[99]=>
array(0) {
}
[16]=>
array(0) {
}
}
}
}
}
EDIT: unset $childrenTable in the end to clear reference flags. In practice, you will probably want to do the operation inside a function anyway.
This question and it's answers should be helpful to you: turn database result into array.
Be sure to read the PDF presentation by #Bill Karwin, specifically the topics regarding the Closure table.

Categories