Consider the factors of the following two numbers...
120: 2, 2, 2, 3, 5
240: 2, 2, 2, 2, 3, 5
I'm trying to identify the matching prime factor pairs, and multiply them together. I have each these listed in two arrays: $factor_list_1 and $factor_list_2
Using: $commons = array_intersect_assoc($factor_list_1, $factor_list_2);
gives: Array ( [0] => 2 [1] => 2 [2] => 2 )
Incorrect
Using: $commons = array_intersect($factor_list_1, $factor_list_2);
gives: Array ( [0] => 2 [1] => 2 [2] => 2 [3] => 3 [4] => 5 )
Correct
However, if I the numbers are 99 and 957, we get...
99: 3, 3, 11
957: 3, 11, 29
I'm trying to identify the matching prime factor pairs, and multiply them together. I have each these listed in two arrays: $factor_list_1 and $factor_list_2
Using: $commons = array_intersect_assoc($factor_list_1, $factor_list_2);
gives: Array ( [0] => 3 ) `
Incorrect
Using: $commons = array_intersect($factor_list_1, $factor_list_2);
gives: Array ( [0] => 3 [1] => 3 [2] => 11 )
Incorrect
I'm randomly generating the numbers, so any ideas on a way to do this that correctly identifies matching pairs of prime factors?
$l = array(2, 2, 2, 3, 5);
$r = array(2, 2, 2, 2, 3, 5);
$cnt_l = array_count_values($l);
$cnt_r = array_count_values($r);
$result = array();
foreach ($cnt_l as $number => $count) {
if (isset($cnt_r[$number])) {
$result = array_merge($result, array_fill(0, min($count, $cnt_r[$number]), $number));
}
}
var_dump($result);
So you:
count how many times every factor occurs
check if it's in another array
append the factor N times into the result array
Just use array_product(array_intersect()).
Related
This question already has answers here:
Add elements to array which has gapped numeric keys to form an indexed array / list
(5 answers)
Closed 5 months ago.
I have a following indexed array
$export_data = array (
[0] => 1,
[1] => 2,
[2] => 3,
[3] => 4,
[4] => 5,
[8] => 9,
[9] => 10,
);
I know how to export it to csv using fputcsv. However what my issue is that I need to export the data into correct column i.e. value in $export_data[8] needs to be exported in column 9 not column 6.
How can this be done please ?
Here you go, boss.
$export_data = array_replace(array_map(function($v){return null;}, range(0, max(array_keys($export_data)))), $export_data);
Tested 100,000 iterations and results are in seconds:
Version Run1 Run2 Run3
PHP 5.6.20 .58 .55 .50
PHP 7.0.5 .18 .21 .21
Now for the explanation so I don't get flogged with downvotes or get accused of witchcraft.
$export_data = array (
0 => 1,
1 => 2,
2 => 3,
3 => 4,
4 => 5,
8 => 9,
9 => 10,
);
$export_data =
array_replace( // replace the elements of the 10-item array with your original array and the filled-in blanks are going to be null. I did not use array_merge() because it would append $export_data onto our dynamic range() array rather than replacing elements as needed.
array_map( // loop the 10-item array and apply the declared function per element. This function ends up returning the 10-item array with all keys intact but the values will be null
function($v){return null; /* return ''; // if you prefer and empty string instead of null*/}, // set each value of the 10-item array to null
range( // create an 10-item array with indexes and values of 0-9
0,
max(array_keys($export_data)) // get the highest key of your array which is 9
)
),
$export_data // your original array with gaps
);
var_dump($export_data);
print_r($export_data);
if i understand correctly, you want to put free columns between data, so the keys match column number.
$arr = array(
0 => 1,
1 => 2,
2 => 3,
3 => 4,
4 => 5,
8 => 9,
9 => 10,
);
$csvArray = array();
$maxKey = max(array_keys($arr));
for($i = 0; $i <= $maxKey; $i++){
if(array_key_exists($i, $arr)){
$csvArray[$i] = $arr[$i];
} else {
$csvArray[$i] = null;
}
}
print_r($csvArray);
demo here: live demo
to describe it, just cycle through array and check wether key is set, if is, assing its value to the next array, if is not, assign null
Optimized:
$csvArray = array();
$maxKey = max(array_keys($arr));
// ++$i is microscopically faster when going for the long haul; such as 10,000,000 iterations
// Try it for yourself:
// $start = microtime(true);
// for($i=0; $i<10000000; $i++){}
// echo (microtime(true) - $start).' seconds';
for($i = 0; $i <= $maxKey; ++$i){
// we can use isset() because it returns false if the value is null anyways. It is much faster than array_key_exists()
$csvArray[$i] = (isset($arr[$i]) ? $arr[$i] : null);
}
I would just fill the array completely with empty values for the empty columns:
$export_data = array (
[0] => 1,
[1] => 2,
[2] => 3,
[3] => 4,
[4] => 5,
[5] => '',
[6] => '',
[7] => '',
[8] => 9,
[9] => 10,
);
Without the indexes (because they are automatic in any case):
$export_data = array (
1,
2,
3,
4,
5,
'',
'',
'',
9,
10,
);
I have a multidimensional array. I need to check if any value in this array has contain same value. If, then execute. What is the better way to check this, or the simplest way TIA
$array[] = array(5, 10, 15, 20, 25, 30);
$array[] = array(1, 2, 3, 4, 5, 6);
$array[] = array(2, 6, 8, 10, 12, 14);
Array
(
[0] => Array
(
[0] => 5
[1] => 10
[2] => 15
[3] => 20
[4] => 25
[5] => 30
)
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
[2] => Array
(
[0] => 2
[1] => 6
[2] => 8
[3] => 10
[4] => 12
[5] => 14
)
)
If I understood your question correctly, you are looking for a way of finding values that appears in more than one of the inner arrays..? Here are two solutions for that, using some built-in PHP array methods.
Setup
Flatten $array (initial step for both methods) using array_merge on itself
Code:
$array[] = array(5, 10, 15, 20, 25, 30);
$array[] = array(1, 2, 3, 4, 5, 6);
$array[] = array(2, 6, 8, 10, 12, 14, 5);
// 5, 10, 15, 20, 25, 30, 1, 2, 3, 4, 5, 6, 2, 6, 8, 10, 12, 14, 5
$array = call_user_func_array('array_merge', $array);
Method A
Get an array of unique values in $array (duplicates removed)
Get what was removed (= the duplicates) by comparing that array to the original $array
Make sure values appear only once in the final array
Code:
$duplicates =
array_unique(
array_diff_key(
$array,
array_unique($array)
)
);
// $duplicates = 5, 2, 6, 10
Method B
Get a list of how many times each value appears in $array
Filter that list keeping only values that appears more than once (= duplicates)
Get the keys of that list (the actual $array values)
Code:
$duplicates =
array_keys(
array_filter(
array_count_values($array),
function ($count) {
return $count > 1;
}
)
);
// $duplicates = 5, 10, 2, 6
Just loop through the array and subarray filling $isRepeated with values and frequencies of appearance. When $isRepeated[certain_value] exists means this value was found before:
$array[] = array(5, 10, 15, 20, 25, 30);
$array[] = array(1, 2, 3, 4, 5, 6);
$array[] = array(2, 6, 8, 10, 12, 14);
$isRepeated = array();
foreach($array as $subArray) {
foreach($subArray as $item) {
if (!isset($isRepeated[$item])) {
$isRepeated[$item] = 0;
} else {
$isRepeated[$item]++;
echo "\n<br>Item $item is repeated";
}
}
}
http://ideone.com/9yObII
Output:
Item 5 is repeated
Item 2 is repeated
Item 6 is repeated
Item 10 is repeated
Struggling with concept of an associative array that maps userIDs to partIDs and re-order quantity for the part.
We have bunch of parts that I need to re-order, but I must keep track of which user needs what parts re-purchased for them. The list of UserIDs comes from one table, then the inventory_used comes from another table.
Suppose a list like this:
Example One:
UserID PartID Qty_Used
1 3 2
1 4 7
2 1 4
2 4 3
3 3 5
After creating an array with the above information, I must create a re-order form (table) for the parts. Therefore, ignoring the userID, group them by the partID, and sum up the total Qty (per part). The re-order table should look something like this:
Example Two:
PartID Qty_to_Reorder
1 4
3 7
4 10
I know I'm going to take a ton of downvotes for failing to show code, but I can't wrap my mind around this seemingly simple problem. (This is for my office, not a school project).
How do I:
(1) Structure the first array (what would the loop to create it look like?), and then
(2) Loop through that array to summarize/group partIDs => Qty for re-order report, as per 2nd example above?
For the first loop, i was thinking of something like this:
Loop through UserIDs {
Loop through PartIDs {
$arrReorder[UserID][PartID] = Qty_Used;
}
}
Is that correct? How would I loop through $arrReorder to sum-up the qty used for each partID, and get the re-order report (example 2)?
SELECT SUM(Qty_Used) AS total FROM mytable WHERE PartID=3
PS: Using PHP
<?php
$data = array();
$data[] = array("UserID" => 1, "PartID" => 3, "Qty_Used" => 2);
$data[] = array("UserID" => 1, "PartID" => 4, "Qty_Used" => 7);
$data[] = array("UserID" => 2, "PartID" => 1, "Qty_Used" => 4);
$data[] = array("UserID" => 2, "PartID" => 4, "Qty_Used" => 3);
$data[] = array("UserID" => 3, "PartID" => 3, "Qty_Used" => 5);
$PartID = 3;
$sum = 0;
foreach ($data as $arr) {
if ($arr['PartID'] == $PartID)
$sum += $arr['Qty_Used'];
}
echo $PartID."\t".$sum."\r\n";
?>
Arrays have a key and value where the value can be another array. Determine what is the key value.
I am assuming you have users consuming parts and you have to re-order the parts from your supplier. No where the user is a customer and the user has a auto re-order policy.
What triggers a reorder? If re-order quantity is 10 and user uses 1, there should be nine in stock.
Create the partsUsed array elements, This is a bit tricky:
$partsUsed[$part][] = array($qtyUsed,$user);
The reason the empty brackets [] is there is to allow duplicate part numbers in the parts used, and still key part as the key.
The value is an array to key the association between user and parts.
what you end up with is a sequentially numbered secondary key where the value is just a throw away, but allows duplicate part numbers.
$partsUsed[3][] = array(2,1);
$partsUsed[4][] = array(7,1);
$partsUsed[1][] = array(4,2);
$partsUsed[4][] = array(3,2);
$partsUsed[3][] = array(5,5);
ksort($partsUsed); // sorts key on part number
var_export($partsUsed);
Result array (var_export):
array (
1 =>
array (
0 =>
array (
0 => 4,
1 => 2,
),
),
3 =>
array (
0 =>
array (
0 => 2,
1 => 1,
),
1 =>
array (
0 => 5,
1 => 5,
),
),
4 =>
array (
0 =>
array (
0 => 7,
1 => 1,
),
1 =>
array (
0 => 3,
1 => 2,
),
),
)
Notice part 3 and 4 have two arrays.
$reorder[1] = 4 ;
$reorder[2] = 7 ;
$reorder[4] = 10 ;
var_export($reorder);
Result array:
array (
1 => 4,
2 => 7,
4 => 10,
)
Now not sure how to determine what gets reordered and how many.
I'll show how to get the values:
foreach($partsUsed as $part => $value){
foreach($value as $k => $v){
echo "Part $part: Qty:$v[0] User:$v[1]\n";
$qtyUsed[$part] += $v[1];
}
}
var_export($qtyUsed);
Outputs:
Part 1: Qty:4 User:2
Part 3: Qty:2 User:1
Part 3: Qty:5 User:3
Part 4: Qty:7 User:1
Part 4: Qty:3 User:2
$qtyUsed
array (
1 => 2,
3 => 4,
4 => 3,
)
foreach ($qtyUsed as $part => $qty){
$order[$part] = $reorder[$part];
}
var_export($order);
Result $order:
array (
1 => 4,
3 => 7,
4 => 10,
)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
So I have an array
array ( 1, 2, 2, 5, 4, 5, 4, 1, 1, 5 ) and I need to collect same array values and divide it to different arrays. So after this action from this array I should have 4 different arrays:
array ( 1, 1, 1 )
array ( 2, 2 )
array ( 5, 5, 5 )
array ( 4, 4 )
what is the best way to do it?
$result = [];
foreach (array_count_values($values) as $value => $occurrence) {
$result[] = array_fill(0, $occurrence, $value);
}
This assumes that the individual value identity doesn't matter, i.e. that you don't have objects whose individual instance you need.
Though I'm not sure why you'd need that particular array format then in the first place. Just use the result of array_count_values.
$input = array ( 1, 2, 2, 5, 4, 5, 4, 1, 1, 5 );
$output = array();
foreach ($input as $value)
$output[$value][] = $value;
var_dump($output)
You can make another array, with the distinct values as the array keys.
<?php
$array = array(1, 2, 2, 5, 4, 5, 4, 1, 1, 5);
$result = array();
foreach ($array as $val) {
if (!isset($result[$val])) { // Check if the index exists
$result[$val] = array();
}
$result[$val][] = $val;
}
print_r($result);
You can try something like below
<?php
$a = array ( 1, 2, 2, 5, 4, 5, 4, 1, 1, 5 );
$a = array_count_values($a);
$arr = array();
foreach($a as $k=>$v){
for($i = 0; $i < $v; $i++){
$arr[$k][] = $k;
}
}
print_r($arr );
?>
Output:
Array
(
[1] => Array
(
[0] => 1
[1] => 1
[2] => 1
)
[2] => Array
(
[0] => 2
[1] => 2
)
[5] => Array
(
[0] => 5
[1] => 5
[2] => 5
)
[4] => Array
(
[0] => 4
[1] => 4
)
)
I've got the following array, containing ordered but non consecutive numerical keys:
Array
(
[4] => 2
[5] => 3
[6] => 1
[7] => 2
[8] => 1
[9] => 1
[10] => 1
)
I need to split the array into 2 arrays, the first array containing the keys below 5, and the other array consisting of the keys 5 and above. Please note that the keys may vary (e.g. 1,3,5,10), therefore I cannot use array_slice since I don't know the offset.
Do you know any simple function to accomplish this, without the need of using a foreach ?
Just found out array_slice has a preserve_keys parameter.
$a = [
4 => 2,
5 => 3,
6 => 1,
7 => 2,
8 => 1,
9 => 1,
10 => 1
];
$desired_slice_key = 5;
$slice_position = array_search($desired_slice_key, array_keys($a));
$a1 = array_slice($a, 0, $slice_position, true);
$a2 = array_slice($a, $slice_position, count($a), true);
you could use array_walk, passing in the arrays you wish to add the keys to by reference using the use keyword - something along the lines of this should work:
$splitArray = [1 => 2, 3 => 1, 5 => 2, 7 => 1, 9 => 3, 10 => 1];
$lt5 = [];
$gt5 = [];
array_walk($splitArray, function(&$val, $key) use (&$lt5, &$gt5) {
$key < 5 ? $lt5[] = $key : $gt5[] = $key;
});
var_dump($lt5, $gt5);