How to get rid of duplicate values from multidimensional array - php

I want to remove duplicate values from multi-dim array, I tried all the possible solutions which is already described but for me, is not working, can anyone please correct it?
Here's my Array:
Array (
[0] => Array (
[0] => element_10
[1] => block_1
[2] => element_4
[3] => element_1
[4] => element_3
)
[1] => Array (
[0] => block_1
[1] => block_2
[2] => element_8
[3] => element_10
[4] => element_12
[5] => element_14
[6] => element_4
[7] => element_2
[8] => element_3
[9] => element_9
[10] => element_13
[11] => element_7
)
)
Where I want the array in this format:
Array (
[0] => Array (
[0] => element_10
[1] => block_1
[2] => element_4
[3] => element_1
[4] => element_3
)
[1] => Array (
[1] => block_2
[2] => element_8
[4] => element_12
[5] => element_14
[7] => element_2
[9] => element_9
[10] => element_13
[11] => element_7
)
)
Ican setup the key indexes later.
I tried:
function multi_unique($array) {
foreach ($array as $k=>$na)
$new[$k] = serialize($na);
$uniq = array_unique($new);
foreach($uniq as $k=>$ser)
$new1[$k] = unserialize($ser);
return ($new1);
}
No Luck, then I tried:
function array_unique_multidimensional($input)
{
$serialized = array_map('serialize', $input);
$unique = array_unique($serialized);
return array_intersect_key($input, $unique);
}
Still same array returning.
I tried this method too:
function super_unique($array)
{
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($result as $key => $value)
{
if ( is_array($value) )
{
$result[$key] = self::super_unique($value);
}
}
return $result;
}
Please help me, I know it's pretty simple I don't know where I'm losing?
Thanks,

You need to iterate over your list of input arrays. For each value in that array, you need to see if you've previously encountered it, so you'll have to keep a super-set of all values across all arrays, which you gradually append to. If a value already exists in the super-set array, you can remove it, otherwise you can append it.
function multi_unique($arrays) {
$all_values = array();
foreach ($arrays as &$array) {
foreach ($array as $index => $value) {
if (in_array($value, $all_values)) {
// We've seen this value previously
unset($array[$index]);
} else {
// First time we've seen this value, let it pass but record it
$all_values[] = $value;
}
}
}
return $arrays;
}
$values = array (
array ( 'element_10', 'block_1', 'element_4', 'element_1', 'element_3',) ,
array ( 'block_1', 'block_2', 'element_8', 'element_10', 'element_12', 'element_14', 'element_4', 'element_2', 'element_3', 'element_9', 'element_13', 'element_7',)
);
var_dump(multi_unique($values));
Output:
array(2) {
[0]=>
array(5) {
[0]=>
string(10) "element_10"
[1]=>
string(7) "block_1"
[2]=>
string(9) "element_4"
[3]=>
string(9) "element_1"
[4]=>
string(9) "element_3"
}
[1]=>
array(8) {
[1]=>
string(7) "block_2"
[2]=>
string(9) "element_8"
[4]=>
string(10) "element_12"
[5]=>
string(10) "element_14"
[7]=>
string(9) "element_2"
[9]=>
string(9) "element_9"
[10]=>
string(10) "element_13"
[11]=>
string(9) "element_7"
}
}

If you just want to remove duplicates from the second entry of your array, use array_diff():
$array[1] = array_diff($array[1], $array[0]);
Iterate if you want to apply it to an arbitrary length.

Why are you using the serialize function.
Use array_diff instead.
A simple would be.
$orginal = array(array(values), array(values), ...);
$copy = $original;
foreach($original as $k => $subArray) {
$tmpCopy = $copy;
unset($tmpCopy[$k]);
unshift($tmpCopy, $subArray);
$tmpCopy = array_values($tmpCopy);
$original[$k] = call_user_func_array('array_diff', $tmpCopy);
}
This works for a two dimensions array.
Hope it helps.

Related

PHP Arrays - read from CSV file, make first column key, second column value

I have a CSV file as follows:
first-key,first-value
second-key,second-value
third-key,third-value
fourth-key,fourth-value
I am reading these in to an array using:
$tmp_array = array_map('str_getcsv', file('./values.csv'));
However, this results in this array:
Array
(
[0] => Array
(
[0] => first-key
[1] => first-value
)
[1] => Array
(
[0] => second-key
[1] => second-value
)
[2] => Array
(
[0] => third-key
[1] => third-value
)
[3] => Array
(
[0] => fourth-key
[1] => fourth-value
)
)
What I would like is this array:
Array
(
[first-key] => first-value
[second-key] => second-value
[third-key] => third-value
[fourth-key] => fourth-value
)
One way I can achieve this is by doing this:
$tmp_array = array_map('str_getcsv', file('./values.csv'));
$array = [];
foreach ($tmp_array as $row) {
$array[$row[0]] = $row[1];
}
Is there a better way of doing this? Perhaps using array_map()?
It depends on your definition of better in this context. I think your solution is good enough. Is better:
not using foreach?
less lines?
less variables?
using more standard library functions?
I want to post 2 propositions:
// 1
$tmp = array_map('str_getcsv', file('data.csv'));
$data = array_combine(array_column($tmp, 0), array_column($tmp, 1));
var_dump($data);
// 2
$data = [];
array_walk(
$tmp,
function($e) use (&$data) {$data[$e[0]] = $e[1];}
);
var_dump($data);
Output:
array(4) {
["first-key"]=>
string(11) "first-value"
["second-key"]=>
string(12) "second-value"
["third-key"]=>
string(11) "third-value"
["fourth-key"]=>
string(12) "fourth-value"
}
array(4) {
["first-key"]=>
string(11) "first-value"
["second-key"]=>
string(12) "second-value"
["third-key"]=>
string(11) "third-value"
["fourth-key"]=>
string(12) "fourth-value"
}

PHP Multidimensional array - Remove part duplicates and add up

I have a multidimensional array like so:
array(4) {
[0] => array(2) {
[0] => string(15)
"One"
[1] => string(5)
"11:31"
}
[1] => array(2) {
[0] => string(4)
"Two"
[1] => string(5)
"11:31"
}
[2] => array(2) {
[0] => string(15)
"Three"
[1] => string(5)
"11:31"
}
[3] => array(2) {
[0] => string(4)
"One"
[1] => string(5)
"11:31"
}
}
I am trying to get the ones with the first value removed but added up together. So it would end up like so:
array(3) {
[0] => array(2) {
[0] => string(15)
"One"
[1] => string(5)
"22:62"
}
[1] => array(2) {
[0] => string(4)
"Two"
[1] => string(5)
"11:31"
}
[2] => array(2) {
[0] => string(15)
"Three"
[1] => string(5)
"11:31"
}
}
Note the last 'One' has been removed and the second value in the array has been added up there from two 11:31's to 22:62. I hope that makes sense.
Is there something or a specific function I should look at to push me in the right direction? Any help much appreciated.
This is not just a straight up removing duplicates from what I can tell, as none are ever exactly the same although the second values are in this example, they won't be in live data.
You could make a loop and group elements into a new array using key [0]. It the key doesn't exists in the new array, simply add the new array. Otherwise, you could parse the existing value to add the new value:
$array = [
["One", "11:31"],
["Two", "11:31"],
["Three", "11:31"],
["One", "11:31"],
];
$out = [];
foreach ($array as $item) {
// if $item[0] is not an existing key,
if (!isset($out[$item[0]])) {
// add $item as-is
$out[$item[0]] = $item;
} else {
// parse current time
list($h1, $m1) = explode(':', $item[1]);
$m1 += $h1 * 60;
// parse existing time
list($h2, $m2) = explode(':', $out[$item[0]][1]);
$m1 += $m2 + $h2 * 60;
// compute new time
$h = floor($m1 / 60);
$out[$item[0]][1] = sprintf("%02d:%02d", $h, $m1-$h*60);
}
}
// array_values removes 'named' keys.
print_r(array_values($out));
Output (condensed):
Array
(
[0] => Array ([0] => One [1] => 23:02)
[1] => Array ([0] => Two [1] => 11:31)
[2] => Array ([0] => Three [1] => 11:31)
)

How to create a new key name and combine values in array with PHP?

I have 2 PHP arrays that I need to combine values together.
First Array
array(2) {
[0]=>
array(1) {
["id"]=>
string(1) "1"
}
[1]=>
array(1) {
["id"]=>
string(2) "40"
}
}
Second Array
array(2) {
[0]=>
string(4) "1008"
[1]=>
string(1) "4"
}
Output desired
array(2) {
[0]=>
array(1) {
["id"]=>
string(1) "1",
["count"]=>
string(1) "1008"
}
[1]=>
array(1) {
["id"]=>
string(2) "40",
["count"]=>
string(1) "4"
}
}
As you can see I need to add a new key name (count) to my second array and combine values to my first array.
What can I do to output this array combined?
Try something like the following. The idea is to iterate on the first array and for each array index add a new key "count" that holds the value contained on the same index of the second array.
$array1 = [];
$array2 = [];
for ($i = 0; $i < count($array1); $i++) {
$array1[$i]['count'] = $array2[$i];
}
you can do it like this
$arr1=[["id"=>1],["id"=>40]];
$arr2=[1008,4];
for($i=0;$i<count($arr2);$i++){
$arr1[$i]["count"] = $arr2[$i];
}
Live demo : https://eval.in/904266
output is
Array
(
[0] => Array
(
[id] => 1
[count] => 1008
)
[1] => Array
(
[id] => 40
[count] => 4
)
)
Another functional approach (this won't mutate/change the initial arrays):
$arr1 = [['id'=> "1"], ['id'=> "40"]];
$arr2 = ["1008", "4"];
$result = array_map(function($a){
return array_combine(['id', 'count'], $a);
}, array_map(null, array_column($arr1, 'id'), $arr2));
print_r($result);
The output:
Array
(
[0] => Array
(
[id] => 1
[count] => 1008
)
[1] => Array
(
[id] => 40
[count] => 4
)
)
Or another approach with recursion:
$arr1=[["id"=>1],["id"=>40]];
$arr2=[1008,4];
foreach ($arr1 as $key=>$value) {
$result[] = array_merge_recursive($arr1[$key], array ("count" => $arr2[$key]));
}
print_r($result);
And output:
Array
(
[0] => Array
(
[id] => 1
[count] => 1008
)
[1] => Array
(
[id] => 40
[count] => 4
)
)

Changing \n into ARRAY values within another ARRAY

I have this ARRAY sent from a FORM
Array
(
[0] => one
two
three
[1] => hello
how
are
)
Since the values are sent via textarea from a form, it has line breakers, so I want to make change every into a array field like so:
Array
(
[0] => Array
(
[0] => one
[1] => two
[2] => three
)
[1] => Array
(
[0] => hello
[1] => how
[2] => are
)
)
This is what I have so far:
foreach ($array as &$valor) {
foreach(preg_split("/((\r?\n)|(\r\n?))/", $valor) as $line){
$arraynew[] = $line;
}
}
But I get this result
Array
(
[0] => one
[1] => two
[2] => three
[3] => hello
[4] => how
[5] => are
)
What am I doing wrong? :(
For each key in the POST array, pop a value onto the final array, with it's values containing an array whoses values represent each line in value of the POST array.
<?php
$data = array(
0 => "one\ntwo\nthree",
1 => "hello\nhow\nare"
);
$final = array();
for($i = 0; $i < count($data); $i++) {
$row = preg_split('/\n/', $data[$i]);
if(is_array($row)) {
for($j = 0; $j < count($row); $j++) {
$final[$i][] = $row[$j];
}
}
}
var_dump($final);
array(2) {
[0] =>
array(3) {
[0] =>
string(3) "one"
[1] =>
string(3) "two"
[2] =>
string(5) "three"
}
[1] =>
array(3) {
[0] =>
string(5) "hello"
[1] =>
string(3) "how"
[2] =>
string(3) "are"
}
}
DEMO
Well, you're really working too hard.
array_map(function($e) { return explode("\n", $e); }, $orig_array);
is all you need. You could use preg_split if you really want, but explode is enough.
You can simply do this
$array=array("one\ntwo\nthree","hello\nhow\nare");
$arraynew=array();
foreach ($array as &$valor) {
$arraynewtemp=array();
foreach(preg_split("/((\r?\n)|(\r\n?))/", $valor) as $line){
$arraynewtemp[] = $line;
}
array_push($arraynew,$arraynewtemp);
}
var_dump($arraynew);
Will output
array(2) {
[0]=>
array(3) {
[0]=>
string(3) "one"
[1]=>
string(3) "two"
[2]=>
string(5) "three"
}
[1]=>
array(3) {
[0]=>
string(5) "hello"
[1]=>
string(3) "how"
[2]=>
string(3) "are"
}
}
This should works

PHP recursive array from JSON to key-value to values

I want to apologize in advanced if this was already asked, I'm not exactly sure what this would be called.
I'm storing data from a form into a MongoDB database and I'd like to create defined key-value pairs to make sorting easier.
Using this code I am able to do this with a one-dimensional array, but it does not work with multidimensional arrays:
/* $array = The array */
$new_array = array();
foreach ($array as $key => $value) {
array_push($new_array, array(
'name' => $key,
'value' => $value
));
}
Example:
Input array:
Array
(
[email] => test#mail.com
[name] => John
[sports] => Array
(
[outdoor] => Array
(
[0] => Football
[1] => Baseball
)
[indoor] => Array
(
[0] => Basketball
[1] => Hockey
)
)
)
Output array:
Array
(
[0] => Array
(
[name] => email
[value] => test#mail.com
)
[1] => Array
(
[name] => name
[value] => John
)
[2] => Array
(
[name] => sports
[value] => Array
(
[outdoor] => Array
(
[0] => Football
[1] => Baseball
)
[indoor] => Array
(
[0] => Basketball
[1] => Hockey
)
)
)
)
Notice how it stops at the sports value array and does not change the array within it. How can I continue this pattern throughout all the arrays within it?
You can use recursion:
function keyValue($array){
$new_array = array();
foreach ($array as $key => $value) {
array_push($new_array, array(
'name' => $key,
'value' => is_array($value) ? keyValue($value) : $value
));
}
return $new_array;
}
Try this on for size:
$array = array(
'email' => 'test#email.com',
'name' => 'John',
'sport' => array('Soccor', 'Hockey')
);
$func = function($value, $key) {
$return = array();
$return['name'] = $key;
$return['value'] = $value;
return $return;
};
$parsed = array_map($func, $array, array_keys($array));
For me, this returned:
array(3) {
[0]=>
array(2) {
["name"]=>
string(5) "email"
["value"]=>
string(14) "test#email.com"
}
[1]=>
array(2) {
["name"]=>
string(4) "name"
["value"]=>
string(4) "John"
}
[2]=>
array(2) {
["name"]=>
string(5) "sport"
["value"]=>
array(2) {
["outdoor"]=>
array(2) {
[0]=>
string(8) "Football"
[1]=>
string(8) "Baseball"
}
["indoor"]=>
array(2) {
[0]=>
string(10) "Basketball"
[1]=>
string(6) "Hockey"
}
}
}
}
It is pretty simple to turn associative arrays to JSON objects (StdClass) and vice versa, preserving native data types (int, float, bool). Here's my attempt:
To Key-Value Array
function toKeyValue($values)
{
$result = [];
foreach ($values as $key => $value)
{
if (is_array($value)) {
$result[$key] = toKeyValue($value);
} elseif (is_object($value)) {
$result[$key] = toKeyValue((array) $value);
} else {
$result[$key] = $value;
}
}
return $result;
}
To JSON Object
function toJson($values)
{
return json_decode(json_encode($values));
}
$values should always be an array.

Categories