how to check multidimensional array for duplicated value - php

i have this array and i don't want to remove duplicated values..
i want to check if there are duplicates in the first value or not
( [0] => 1500,[0] => 1111, [0] => 1500)
if there are then return true else return false how to do this ?
Array
(
[0] => Array
(
[0] => 1500
[1] => first
[2] =>
[3] =>
[4] => 50
[5] =>
[6] =>
)
[1] => Array
(
[0] => 1111
[1] => second
[2] =>
[3] =>
[4] => 10
[5] =>
[6] =>
)
[2] => Array
(
[0] => 1500
[1] => third
[2] =>
[3] =>
[4] => 100
[5] =>
[6] =>
)
)

If you have PHP 5.5+ available, the function array_column() makes it easy to extract the first "column" of the sub-arrays, and feed the resultant array to array_count_values(), which would produce an array of values like [1500] => 2, [1111] => 1, from which you can easily deduce which have > 1.
That would look like:
// PHP 5.5+ only...
// Gets counts of each first sub-array value
$counts = array_count_values(array_column($input_multidimensional_array, 0));
// Test that the array key has > 1
// To check a specific one for duplicates:
if (isset($counts['1500']) && $counts['1500'] > 1) {
// Yes, it has duplicates.
}
But... Since you do not have PHP 5.5+, you'll have to use some form of loop.
$temp = array();
foreach ($input_multidimensional_array as $sub_array) {
// A temporary array holds all the first elements
$temp[] = $sub_array[0];
}
// Count them up
$counts = array_count_values($temp);
// Then use the same process to check for multiples/duplicates:
if (isset($counts['1500']) && $counts['1500'] > 1) {
// Yes, it has duplicates.
}
In either of those cases, you could also use array_filter() to only return the array from $counts which had multiples.
// Filter to only those with > 1 into $only_duplicates
$only_duplicates = array_filter($counts, function($v) {
return $v > 1;
});
// To further reduce this only to the _values_ themselves like 1500, 1111
// use array_keys:
$only_duplicates = array_keys($only_duplicates);
// is now array('1500')

Related

Make a new array form multidimensional array based on search conditions

I have a multidimensional array. I want to search values(username IE jon) and count total "YES" for a specific username.
IE As per below array Andew is repeated three times Index 1,3,4 and its value is "YES" So Andrew's total "YES" count value = 3
Jon is repeated two times but its value is "NO" so it's value = 0
Array
(
[0] => Array
(
[0] => Jon
[1] => NO
)
[1] => Array
(
[0] => Andew
[1] => NO
)
[2] => Array
(
[0] => Walid
[1] => YES
)
[3] => Array
(
[0] => Andew
[1] => YES
)
[4] => Array
(
[0] => Andew
[1] => YES
)
[5] => Array
(
[0] => Jon
[1] => NO
)
[6] => Array
(
[0] => Andew
[1] => YES
)
)
I want to make the user as key and value = count the total number of "Yes".
OUTPUT
Array
(
john => 0,
Andew => 3
Walid => 1
)
Anyone, please suggest a possible solution?
Thanks
You may use array_reduce:
$stats = array_reduce($array, static function ($stats, $entry) {
$stats[$entry[0]] = ($stats[$entry[0]] ?? 0) + ($entry[1] === 'YES' ? 1 : 0);
return $stats;
});
This builds up a $stats array, sets its initial value to 0 for each person and increments it by 1 whenever a YES is found.
Demo: https://3v4l.org/NmZ7G
If you just need the count of 'YES', then the below will output a count.
$count_array = [];
foreach($array as $values){
if(!isset($count_array[$values[0]])){
$count_array[$values[0]] = 0;
}
if($values[1] === 'YES'){
$count_array[$values[0]] ++;
}
}
print_r($count_array);
(Not that different from #Jeto's array_reduce.)
A simple foreach:
<?php
$data =
[
['Brian', 'YES'],
['Brian', 'YES'],
['Charles', 'NO'],
['Charles', 'YES'],
['Nicola', 'NO']
];
foreach($data as list($name, $yes_no))
$yes_counts[$name] = ($yes_counts[$name] ?? 0) + (int) ($yes_no === 'YES');
var_export($yes_counts);
Output:
array (
'Brian' => 2,
'Charles' => 1,
'Nicola' => 0,
)

Combine multiple arrays

I have arrays like this
Array 1:
Array
(
[0] => Array
(
[0] => 0
[1] => -0.025
)
[1] => Array
(
[0] => 0
[1] => -0.025
)
[2] => Array
(
[0] => 0
[1] => -0.025
)
)
Array 2:
Array
(
[0] => Array
(
[0] => 0
[1] => -0.025
)
[1] => Array
(
[0] => 0
[1] => -0.025
)
)
Array 3:
Array
(
[0] => Array
(
[0] => 0
[1] => -0.025
)
[1] => Array
(
[0] => 0
[1] => -0.025
)
[2] => Array
(
[0] => 0
[1] => -0.025
)
[3] => Array
(
[0] => 0
[1] => -0.025
)
)
and more of them.
I want to combine them to this
Array
(
[0] => Array
(
[0] => 0
[1] => -0.025
[2] => 0
[3] => -0.025
[4] => 0
[5] => -0.025
)
[1] => Array
(
[0] => 0
[1] => -0.025
[2] => 0
[3] => -0.025
[4] => 0
[5] => -0.025
)
[2] => Array
(
[0] => 0
[1] => -0.025
[2] => 0
[3] => 0
[4] => 0
[5] => -0.025
)
[3] => Array
(
[0] => 0
[1] => 0
[2] => 0 // These (0-3) are 0 because the other two arrays haven't 3 in the first level
[3] => 0
[4] => 0
[5] => -0.025
)
)
The arrays have a different number of entries in the first level. In the second level there are always 2 entries.
In the second level of the combined array the first two keys (0 and 1) should always have the entries from the first array. The second two keys (2 and 3) should always have the entries from the second array and so on. In my example there are 30 arrays that I want to combine.
If an array does have more first level entries than others all entries should have 0 as value.
I hope you understand this :)
I built it ;-/
Working demonstration at eval.in
Requirements:
Basically it is transposing rows into columns.
the output columns all have the length of the longest array.
The source arrays can have different lengths. Any empty entries are assumed to have a value of array(0, 0).
The output columns are converted into a single dimensional array. i.e. source value arrays are appended to the column array.
Explanation:
I decided to use the internal iterator that all arrays have. i.e. the arrays already can record there own state such as current position (row) that they are on.
After that it is just 'housekeeping':
keep a list of which arrays still have entries to be processed. When none of them have then we are finished.
record which output column ($mergedEntryNo) that we are creating.
scan along each (row) reading entries for the current row.
after each row: advance to the next row and record which arrays are active - if any.
The class (SimpleMerge) that does the work
class SimpleMerge {
protected $sources = array(); // a list of arrays!
protected $sourceCount = 0; // useful
protected $isActive = array(); // which of them have entries to process.
public $merged = array(); // output in here and public
protected $anyActiveSources = false;
// need a list of arrays
public function __construct(array $allSources)
{
$this->sources = $allSources;
$this->sourceCount = count($allSources);
$this->isActive = array_fill(0, $this->sourceCount, true);
}
// generate the output by scanning the arrays line by line
public function generateOutput()
{
$this->generateInit();
$mergedEntryNo = 0;
while ($this->anyActiveSources) {
// set the next output entries
for ($sourceNo = 0; $sourceNo < $this->sourceCount; $sourceNo++) {
$this->addEntry($mergedEntryNo, $this->getEntry($sourceNo));
}
$mergedEntryNo++;
$this->nextPassAdvance();
$this->setIsActiveSource();
}
return $this->merged;
}
// ensure everything is initialized correctly
public function generateInit()
{
$this->merged = array();
foreach ($this->sources as &$source) {
reset($source); // force internal iterators to the start
$this->merged[] = array(); // empty arrays in the output
}
unset($source);
$this->setIsActiveSource();
}
// add to output
public function addEntry($mergedNo, array $values)
{
foreach ($values as $value) {
$this->merged[$mergedNo][] = $value;
}
}
// get the current source entry - will be array of zeroes if end of array
public function getEntry($sourceNo)
{
if ($this->isActive[$sourceNo]) {
return current($this->sources[$sourceNo]);
}
else {
return array(0, 0);
}
}
// check and set which ones are still active and also indicate if any are active
public function setIsActiveSource()
{
$activeCount = 0;
for ($sourceNo = 0; $sourceNo < $this->sourceCount; $sourceNo++) {
$isActive = current($this->sources[$sourceNo]) !== false;
$this->isActive[$sourceNo] = $isActive;
$activeCount = $activeCount + ($isActive ? 1 : 0);
}
$this->anyActiveSources = $activeCount > 0;
}
// advance iterators on the sources that are still active
public function nextPassAdvance()
{
for ($sourceNo = 0; $sourceNo < $this->sourceCount; $sourceNo++) {
if ($this->isActive[$sourceNo]) { // was last time
next($this->sources[$sourceNo]);
}
}
}
}
Run it
// create and run the generator...
$mergeAll = new SimpleMerge($allSourcesList);
$merged = $mergeAll->generateOutput();
Output:
Note, there are no zero values in the input. The values indicate source table and entry number.
Outpt: Array
(
[0] => Array
(
[0] => 11
[1] => -11.025
[2] => 21
[3] => -21.025
[4] => 31
[5] => -31.025
[6] => 41
[7] => -41.025
)
[1] => Array
(
[0] => 12
[1] => -12.025
[2] => 22
[3] => -22.025
[4] => 32
[5] => -32.025
[6] => 42
[7] => -42.025
)
[2] => Array
(
[0] => 13
[1] => -13.025
[2] => 0
[3] => 0
[4] => 33
[5] => -33.025
[6] => 43
[7] => -43.025
)
[3] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 34
[5] => -34.025
[6] => 44
[7] => -44.025
)
)

PHP: put array entries in new order

I try to take the following array:
Array
(
[0] => Array
(
[1] => 12
[2] => 21
[3] => 33
)
[1] => Array
(
[1] => 5
[2] => 5
[3] => 4
)
[2] => Array
(
[1] => 1
[2] => 10
[3] => 11
)
[3] => Array
(
[3] => 2
)
)
and create a new array with it, taking the first entries of the source array. So the first array from this one would look like this:
Array
(
[0] => 12
[1] => 5
[2] => 1
[3] => 2
)
And the second one obviously like this:
Array
(
[0] => 21
[1] => 5
[2] => 10
)
I tried around with 2 for loops, it somewhat works with
for ($i = 1; $i < count($month_array[$i]) + 1; $i++)
{
unset($temp_array);
for ($i2 = 0; $i2 < count($month_array); $i2++)
{
if (isset($month_array[$i2][$i]))
{
$temp_array[] = $month_array[$i2][$i];
}
}
}
But it leaves out some of the elements and if the source array is not complete, meaning only the 3rd array has a value for key 3, it also fails.
Any help ? Many thanks !
Try it like this:
$org_array = array(array(1 => 12,2 => 21,3 => 33),array(1 => 5,2 => 5,3 => 4),array(1 => 1,2 => 10,3 => 11),array(3 => 2),); // your original array
$new_array = array(); // the output array
foreach($org_array as $sub_org_value) { // for each sub array of your original array do this
foreach($sub_org_value as $key => $value) { // for each entry in a sub array do this
$new_array[$key][] = $value; // add the entry into the new_array in the right sub array
}
}
print_r($new_array[1]); // yields 12,5,1
print_r($new_array[2]); // yields 21,5,10
print_r($new_array[3]); // yields 33,4,11,2
Afterwards you have an array $new_array that contains three arrays. The first sub array has all 1 values, the second sub array has all 2 values and the third sub array has all 3 values.

PHP three dimensional array, reset key if second element different

Let say i have this print_r output, this is dynamic and not same each condition
Array
(
[2] => Array
(
[1] => 24
[2] => 23,25
)
[3] => Array
(
[3] => 27
[4] => 27,26
[5] => 28,27,26
)
)
As you can see, array element [3] starts from [3][4][5], how do it make it start from [1][2]...[n] if the 2nd element is not same.
Ideally what i am looking for is something like
Array
(
[2] => Array
(
[1] => 24
[2] => 23,25
)
[3] => Array
(
[1] => 27
[2] => 27,26
[3] => 28,27,26
)
)
How do i achieve that? Thanks
array_values returns the values of an array with new numeric indices:
foreach($a as $k => $v) {
$a[$k] = array_values($v);
}
Add conditions if you only want to re-index some of your sub-arrays.
Functional approach:
$a = array_map(function($v) {
return array_values($v);
}, $a);

how to push data into array in php

Dear All,
I want to push the data into array. i am using flowing code. There are two arrays. one holding keys and 2nd values. i am using flowing code
while($data=mysql_fetch_array($result))
{
foreach ($arrTemp as $val)
{
array_push($arrKeys, $val);
array_push($arrValues, $data[$val]);
}
}
print_r($arrKeys);
print_r($arrValues);
$arrReturn = array_combine($arrKeys,$arrValues);
...................................
and get flowing results of two arrays.
Array ( [0] => due_date [1] => flag_code [2] => due_date [3] => flag_code [4] => due_date [6] => flag_code )
Array ( [0] => 12:04:2011 [1] => 0 [2] => 13:04:2011 [3] => 0 [4] => 14:04:2011 [6] => 0 )
when i try to combined the array using array_combined function it only return an array of two values like: Array (due_date => 14:04:2011 flag => 0)
how i can get all values in single array.....!
Its because your have multiple the same array keys. So first it inserts due_date, then flag_code, then it will try and insert another due_date but since this already exists in the array it will overwrite it. Thus the only values left in the array will be the last pair.
The solution is to not have multiple keys that are the same in one array (your due_date and flag_code)
You could do:
foreach ($arrTemp as $val) {
$arrReturn[] = array($val => $data[$val];
}
This will give you each set of results keyed in an array like so:
$arrReturn[0] = array (due_date => 14:04:2011 flag => 0);
$arrReturn[1] = array (due_date => 14:04:2011 flag => 0);
$arrReturn[2] = array (due_date => 14:04:2011 flag => 0);
...
$ctr = 0;
foreach ($arrKeys as $id => $key) {
$res_array[$ctr][$key] = $arrValues[$id];
if ($key == 'flag_code') $ctr++;
}
print_r($res_array);
Output:
Array
(
[0] => Array
(
[due_date] => 12:04:2011
[flag_code] => 0
)
[1] => Array
(
[due_date] => 13:04:2011
[flag_code] => 0
)
[2] => Array
(
[due_date] => 14:04:2011
[flag_code] => 0
)
)

Categories