compare values in array and delete it from array - php - php

array:
[0] => Array
(
[0] => A
[1] => 70H
[2] => 51.57
[3] => RH
)
[1] => Array
(
[0] => B
[1] => 70H
[2] => 39.11
[3] => RH
)
[2] => Array
(
[0] => C
[1] => 70H
[2] => 12.11
[3] => RH
)
This is just an example of an array, my real array is really big.
I want to find the same values in array like this [key][1], compare their price, find the lowest PRICE [KEY][2]and save [key][0] for all other elements, if the price is the same then random save one as lowest. In the example i give the result that i want will be:
[0] A
[1] B
I tried this code but it doesn't work for me:
$res=array();
$Mfr= arrays_column($final_array, 1);
$dupes = array_diffs(array_count_values($Mfr), array(1)); // how many times a mfr sku appears
print "\nThese are repetitive values:\n[mfrsku] => (number of reps)\n";
foreach($dupes as $key => $val){
$temp = array_intersect_key(arrays_column($final_array, 3), $key);
if(count(array_unique($temp)) < count($temp)){
$temp = array_intersect_key(arrays_column($final_array, 2), array_intersect($Mfr, array($key)));
$temp = array_diffs($temp, array(min($temp)));
$res[] = array_intersect_key(arrays_column($final_array, 0), $temp);
print_r($res);die;
}
}

You can collect during first foreach loop all minimum values and then easily collect records which have another values:
Declaring arrays
$minvals = []; // array of minimum values
$spec = []; // resultant array
$tmp = []; // tmp array (needs for similar records)
First array (collecting minimum values(prices)):
foreach($ar as $rec){
$val = $rec[2]; // price
if(isset($minvals[$rec[1]] )) { // next appearance of the same $rec[1]
if ($minvals[$rec[1]] >= $val) {
$minvals[$rec[1]] = $val;
}
} else { // first appearance
$minvals[$rec[1]] = $val;
}
}
Now you can collect desired values of from the first column:
foreach($ar as $rec){
if ($rec[2] > $minvals[$rec[1]]){ // if price is bigger than minimum
$spec[] = $rec[0];
} else if($rec[2] == $minvals[$rec[1]]){ // if equal
if(isset($tmp[$rec[1]])){ // if it appears at not the first time
$spec[] = $rec[0];
} else {
$tmp[$rec[1]] = 1;
}
}
}
In case of input array like:
$ar = [ ["A","70H","51.57","RH"],
["B","70H","39.11","RH"],
["C","70H","12.11","RH"],
["A2","71H","11.57","RH"],
["B2","71H","32.11","RH"],
["C2","73H","12.11","RH"],
["C3","73H","11.11","RH"],
["C4","73H","33.11","RH"],
["C5","73H","3.11","RH"],
["C6","73H","3.11","RH"],
];
Outputs would be next:
Array
(
[0] => A
[1] => B
[2] => B2
[3] => C2
[4] => C3
[5] => C4
[6] => C6
)
Demo

Related

Combining Arrays while merging the values with the same key

I have two arrays with same amount of values. I need to combine them ( array1 value to key, array2 value as value) without losing the values of the second array due to duplicate key. when I use combine_array() as expected it just gets the last value of the second array with the same key.
Array
(
[0] => 1
[1] => 2
[2] => 2
[3] => 3
)
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
Desired result
Array
(
[1] => 1
[2] => Array(
[0]=>2
[1]=>3
)
[3] => 2
)
This code will meet your request
$array1 = array("0"=>1,"1"=>2,"2"=>2,"3"=>3);
$array2 = array("0"=>1,"1"=>2,"2"=>3,"3"=>4);
$array = array();
foreach($array1 as $key => $value){
if($value != $array2[$key]){
$array[$key][] = $value;
$array[$key][] = $array2[$key];
}else{
$array[$key] = $value;
}
}
print_r($array);
The desired result is
Array
(
[0] => 1
[1] => 2
[2] => Array
(
[0] => 2
[1] => 3
)
[3] => Array
(
[0] => 3
[1] => 4
)
)
I'm sure there are way better solutions than this, but it does the job for now. I would appreciate if someone can send a better written solution.
$combined = array();
$tempAr = array();
$firstMatch = array();
$count = 0;
foreach ($array1 as $index => $key) {
if (array_key_exists($key, $combined)) {
$tempAr[] = $array2[$index];
$count++;
} else {
$totalCount = $count;
}
if (!array_key_exists($key, $firstMatch)) {
$firstMatch[$key] = $array2[$index];
}
$output = array_slice($tempAr, $totalCount);
$combined[$key] = $output;
}
$combined = array_merge_recursive($firstMatch, $combined);

php split array on change of value in column data

I am trying to split array data into multiple arrays based on change in data value at known position (column).
$input = array(
array(1,2,3),
array(4,5,3),
array(7,8,4),
array(9,10,4),
array(11,12,4)
);
Here column 3 changes values from 3 to 4
and expected result is to have 2 arrays
$out1 = array(array(1,2,3),array(4,5,3));
$out2 = array(array(7,8,4), array(9,10,4), array(11,12,4));
since number of rows are variable, cannot use array_chunk
since column 3 values are variable, cannot use array_filter
number of output arrays are also variable.
trying splice but failing...
You can use array_reduce to make new array, where index will be equal to last numbers in items
$new = array_reduce($input, function($c, $x) { $c[$x[2]][] = $x; return $c; }, [] );
$out1 = $new[3];
$out2 = $new[4];
demo
But if array is not sorted and you want to split at points of changing that number, the code can be
$i = -1;
$last = null;
$new = [];
foreach($input as $x) {
if ($x[2] != $last) {
$i++;
$last = $x[2];
}
$new[$i][] = $x;
}
demo
You can use split index with index of array,
$out1 = $out2 = [];
$splitIndex = 2;
foreach($input as $k => $v){
if($k < $splitIndex){
$out1[] = $v;
}else{
$out2[] = $v;
}
}
print_r($out1);
print_r($out2);
Working demo
Output:-
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4
[1] => 5
[2] => 3
)
)
Array
(
[0] => Array
(
[0] => 7
[1] => 8
[2] => 4
)
[1] => Array
(
[0] => 9
[1] => 10
[2] => 4
)
[2] => Array
(
[0] => 11
[1] => 12
[2] => 4
)
)

Convert complex numerical array to associative array

I have an array data that look like this :
Array (
[0] => Array (
[0] => Name:
[1] => John W.
[2] => Registration ID:
[3] => 36
)
[1] => Array (
[0] =>Age:
[1] => 35
[2] => Height:
[3] => 5'11"
)
[3] => Array (
[0] => Sex:
[1] => M
[2] => Weight:
[3] => 200lbs
)
[4] => Array (
[0] => Address
)
[5] => Array (
[0] => 6824 crestwood dr delphi, IN 46923
))
And I want to convert it to associative array like this :
Array(
['Name']=> John W.
['Registration ID']=> 36
['Age']=> 35
['Height'] => 5'11''
['Sex']=>M
['Weight']=>200lbs
['Address']=>6824 crestwood dr delphi, IN 46923
)
I have no idea at all how to do this, since the supposed to be array column header were also in sequence, so it makes difficult to convert this array.
Any help I appreciate, thx.
Given your origin array is called $origin , you can do it like this:
$merged = array();
foreach($origin as $val) {
$merged = array_merge($merged, $val);
}
$tot = count($merged) - 1;
for ($i=0;$i<$tot;$i+=2) {
$result[$merged[$i]] = $merged[$i+1];
}
var_dump($result); // To test the resulting array
Firstly, I use array_merge() to flatten the $origin array to only one dimension/depth, so we later iterate it (stepping each 2 items per iteration) and assigning each pair of items ($i and $i+1) to the resulting array.
Looks like, for the first 3 children, you can just assign the even value to the previous element as key. Then, assign the fourth one as key for fifth element.
$result = array();
foreach ($array as $key => $value)
{
if ($key < 4) {
$elements = array_values($value);
$result[$elements[0]] = $elements[1];
$result[$elements[2]] = $elements[3];
}
if ($key == 4)
$fifthkey = $value;
if ($key == 5)
$result[$fifthkey] = $value;
}
Also, note that you have to escape your height string quotes.

Sorting sub array values in MultiDimension Array

I am trying to sort an array sent from an XML feed.
The Array looks like this from print_r($answer);:
Array
(
[size] => Array
(
[0] => 1.5m x 1.5m
[1] => 1.5m x 3m
[2] => 3m x 6.0m
[3] => 3m x 2.3m
)
[rate] => Array
(
[0] => 80
[1] => 135
[2] => 295
[3] => 180
)
[sortorder] => Array
(
[0] => 3
[1] => 4
[2] => 1
[3] => 2
)
.
.
.
)
I want to get out the array:
Array
(
[size] => Array
(
[0] => 3m x 6.0
[1] => 3m x 2.3m
[2] => 1.5m x 1.5m
[3] => 1.5m x 3m
)
[rate] => Array
(
[0] => 295
[1] => 180
[2] => 80
[3] => 135
)
[sortorder] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
.
.
.
)
What I am trying to do is use the Sort Order sub array to display the items in that order
I have tried a number of uasort() and array_multisort() examples, but all seem to order the sub arrays and not the values inside the sub arrays
Any ideas will be a great help. Cheers
This one sorts $answer['sortorder'] and uses those keys to sort the rest of $answer without restructuring first.
// sort $answer['sortorder'] and retrieve indices.
asort($answer['sortorder']);
$idx = array_keys($answer['sortorder']);
// do sorting
$sorted = array();
foreach($answer as $key=>$subarr) {
if ($key != 'sortorder') { // don't sort
foreach($idx as $i) {
$sorted[$key][] = $subarr[$i];
}
} else {
// $answer['sortorder'] is already sorted.
$sorted[$key] = $subarr;
}
}
print_r($sorted);
See it in action here.
This approach will re-structure the array with the sort order being the index, sort the array, then return it to it's original structure.
echo '<pre>';
$array['size'][0] = '1.5m x 1.5m';
$array['size'][1] = '1.5m x 3m';
$array['size'][2] = '3m x 6.0m';
$array['size'][3] = '3m x 2.3m';
$array['rate'][0] = 80;
$array['rate'][1] = 135;
$array['rate'][2] = 295;
$array['rate'][3] = 180;
$array['sortorder'][0] = 3;
$array['sortorder'][1] = 4;
$array['sortorder'][2] = 1;
$array['sortorder'][3] = 2;
$temp = array();
foreach($array['sortorder'] as $key => $value)
{
$temp[$array['sortorder'][$key]] = array(
'size'=>$array['size'][$key],
'rate'=>$array['rate'][$key],
'sortorder'=>$array['sortorder'][$key]
);
}
ksort($temp);
$array = array();
foreach($temp as $key => $value)
{
$array['size'][] = $value['size'];
$array['rate'][] = $value['rate'];
$array['sortorder'][] = $value['sortorder'];
}
print_r($array);
May I propose to use a different array structure that bundles each size, rate and sort order into one item:
array(
array('size' => '...', 'rate' => '...', 'sort order' => '...'),
...
)
That makes it trivial to sort, and in fact easier to work with in general.
This PHP 5.3+ code does this transformation and sorting:
$answer = array_map(function ($size, $rate, $sortorder) {
return compact('size', 'rate', 'sortorder');
}, $answer);
usort($answer, function ($a, $b) { return $a['sortorder'] - $b['sortorder']; });

php split array between two values

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];
}
}
}

Categories