将关联数组简化为随机的唯一值对
Reduce an associative array to randomised pairs of unique values
我正在尝试将关联数组简化为成对的唯一值,键是要配对的字母,值是它们的 count()
s。
每一对不能包含相同的字母两次,例如 AA
或 BB
。
允许同一对出现不止一次。
例如AC
、DC
、AC
、DC
在结果数组
中都是有效的
每选择一个字母,其相关编号就会减一,直到 none 剩余,或者
任何 odd/leftover 字母都应该被标记而不是被忽略,例如Array([paired]=>Array(...) [unpaired]=>Array(...))
示例输入:
Array(
[A] => 8
[B] => 16
[C] => 15
[D] => 4
[E] => 1
)
可能的输出:
[
'paired' => [
'BD', 'AE', 'BC', 'AC', 'BC', ...
],
'unpaired' => [
'C' => 4
]
]
我希望随机选择两个独特的字母,但如果这太难,那么结果数组应该很容易 shuffle()
-able
试过array_reduce()
、array_map()
、array_walk()
、array_unique()
等各种组合,连Pear的Math_Combinatorics
都试过了,但都无济于事.
这是一个可以生成您想要的结果的函数。它遍历 letters
数组,过滤掉已经完全使用的字母,直到只有一个字母未被使用。然后在数组中返回成对列表和未使用的字母:
function random_pairs($letters) {
$pairs = array();
$letters = array_filter($letters);
while (count($letters) > 1) {
$keys = array_keys($letters);
shuffle($keys);
list($letter1, $letter2) = array_slice($keys, 0, 2);
$pairs[] = "$letter1$letter2";
$letters[$letter1]--;
$letters[$letter2]--;
$letters = array_filter($letters);
}
return array('pairs' => $pairs, 'unpaired' => $letters);
}
示例用法:
$letters = array('A' => 8, 'B' => 16, 'C' => 15, 'D' => 4, 'E' => 1);
print_r(random_pairs($letters));
示例输出:
Array
(
[pairs] => Array
(
[0] => CB
[1] => CE
[2] => CD
[3] => BD
[4] => CB
[5] => DC
[6] => AB
[7] => CA
[8] => DA
[9] => BC
[10] => BA
[11] => BA
[12] => AB
[13] => BA
[14] => BC
[15] => AB
[16] => BC
[17] => CB
[18] => CB
[19] => CB
[20] => CB
)
[unpaired] => Array
(
[C] => 2
)
)
我向你推荐这个:
我刚看到 Nick 的回答,但它持续了 15 分钟我正在尝试 xD 我想 post 我的回答 :p
基于“pickRandomValues”函数,我把它变成动态的,你也可以选择你想要的字母数
function pickRandom(&$array = [], $count = 1) {
$valuesFound = [];
if (count($array) >= $count) {
for ($i = 0; $i < $count; $i++) {
$index = rand(0, count($array) - 1);
$tmp = array_splice($array, $index, 1);
$valuesFound[] = $tmp[0];
}
}
return $valuesFound;
}
而你body代码
$tmpArr = [];
foreach ($a as $letter => $count) {
$t = [];
$tmpArr = array_merge($tmpArr, array_pad($t, $count, $letter));
}
$pairs = [];
while (count($tmpArr) >= $numberOfLetters) {
$pick = pickRandom($tmpArr, $numberOfLetters);
$pairs[] = implode($pick);
}
$finalArray = [
"paired" => $pairs,
"unpaired" => array_count_values($tmpArr)
];
所以,它给出了这样的东西:
http://sandbox.onlinephpfunctions.com/code/3b143396b7267bd6029ff613746d6c047557a282
这是一种递归技术。它使用 array_rand()
一次获取两个唯一的键。如果您需要随机排列成对密钥,请对它们调用 shuffle()
。我的意思是,shuffle()
可能会被忽略,具体取决于您的期望。
使用 array_rand()
的一个优点是不需要调用 array_keys()
,因为它 returns 随机键。
我特意设计了这个片段来无条件地声明 unpaired
子数组——即使它是空的。
代码:(Demo)
function randomPairs(array $letters, array $result = []) {
if (count($letters) < 2) {
$result['unpaired'] = $letters;
return $result;
}
$keys = array_rand($letters, 2);
shuffle($keys);
$result['paired'][] = $keys[0] . $keys[1];
--$letters[$keys[0]];
--$letters[$keys[1]];
return randomPairs(array_filter($letters), $result);
}
没有递归:(Demo)
function randomPairs(array $letters): array {
$result['paired'] = [];
while (count($letters) > 1) {
$keys = array_rand($letters, 2);
shuffle($keys);
$result['paired'][] = $keys[0] . $keys[1];
--$letters[$keys[0]];
--$letters[$keys[1]];
$letters = array_filter($letters);
}
$result['unpaired'] = $letters;
return $result;
}
我正在尝试将关联数组简化为成对的唯一值,键是要配对的字母,值是它们的 count()
s。
每一对不能包含相同的字母两次,例如 AA
或 BB
。
允许同一对出现不止一次。
例如AC
、DC
、AC
、DC
在结果数组
每选择一个字母,其相关编号就会减一,直到 none 剩余,或者
任何 odd/leftover 字母都应该被标记而不是被忽略,例如Array([paired]=>Array(...) [unpaired]=>Array(...))
示例输入:
Array(
[A] => 8
[B] => 16
[C] => 15
[D] => 4
[E] => 1
)
可能的输出:
[
'paired' => [
'BD', 'AE', 'BC', 'AC', 'BC', ...
],
'unpaired' => [
'C' => 4
]
]
我希望随机选择两个独特的字母,但如果这太难,那么结果数组应该很容易 shuffle()
-able
试过array_reduce()
、array_map()
、array_walk()
、array_unique()
等各种组合,连Pear的Math_Combinatorics
都试过了,但都无济于事.
这是一个可以生成您想要的结果的函数。它遍历 letters
数组,过滤掉已经完全使用的字母,直到只有一个字母未被使用。然后在数组中返回成对列表和未使用的字母:
function random_pairs($letters) {
$pairs = array();
$letters = array_filter($letters);
while (count($letters) > 1) {
$keys = array_keys($letters);
shuffle($keys);
list($letter1, $letter2) = array_slice($keys, 0, 2);
$pairs[] = "$letter1$letter2";
$letters[$letter1]--;
$letters[$letter2]--;
$letters = array_filter($letters);
}
return array('pairs' => $pairs, 'unpaired' => $letters);
}
示例用法:
$letters = array('A' => 8, 'B' => 16, 'C' => 15, 'D' => 4, 'E' => 1);
print_r(random_pairs($letters));
示例输出:
Array
(
[pairs] => Array
(
[0] => CB
[1] => CE
[2] => CD
[3] => BD
[4] => CB
[5] => DC
[6] => AB
[7] => CA
[8] => DA
[9] => BC
[10] => BA
[11] => BA
[12] => AB
[13] => BA
[14] => BC
[15] => AB
[16] => BC
[17] => CB
[18] => CB
[19] => CB
[20] => CB
)
[unpaired] => Array
(
[C] => 2
)
)
我向你推荐这个:
我刚看到 Nick 的回答,但它持续了 15 分钟我正在尝试 xD 我想 post 我的回答 :p
基于“pickRandomValues”函数,我把它变成动态的,你也可以选择你想要的字母数
function pickRandom(&$array = [], $count = 1) {
$valuesFound = [];
if (count($array) >= $count) {
for ($i = 0; $i < $count; $i++) {
$index = rand(0, count($array) - 1);
$tmp = array_splice($array, $index, 1);
$valuesFound[] = $tmp[0];
}
}
return $valuesFound;
}
而你body代码
$tmpArr = [];
foreach ($a as $letter => $count) {
$t = [];
$tmpArr = array_merge($tmpArr, array_pad($t, $count, $letter));
}
$pairs = [];
while (count($tmpArr) >= $numberOfLetters) {
$pick = pickRandom($tmpArr, $numberOfLetters);
$pairs[] = implode($pick);
}
$finalArray = [
"paired" => $pairs,
"unpaired" => array_count_values($tmpArr)
];
所以,它给出了这样的东西:
http://sandbox.onlinephpfunctions.com/code/3b143396b7267bd6029ff613746d6c047557a282
这是一种递归技术。它使用 array_rand()
一次获取两个唯一的键。如果您需要随机排列成对密钥,请对它们调用 shuffle()
。我的意思是,shuffle()
可能会被忽略,具体取决于您的期望。
使用 array_rand()
的一个优点是不需要调用 array_keys()
,因为它 returns 随机键。
我特意设计了这个片段来无条件地声明 unpaired
子数组——即使它是空的。
代码:(Demo)
function randomPairs(array $letters, array $result = []) {
if (count($letters) < 2) {
$result['unpaired'] = $letters;
return $result;
}
$keys = array_rand($letters, 2);
shuffle($keys);
$result['paired'][] = $keys[0] . $keys[1];
--$letters[$keys[0]];
--$letters[$keys[1]];
return randomPairs(array_filter($letters), $result);
}
没有递归:(Demo)
function randomPairs(array $letters): array {
$result['paired'] = [];
while (count($letters) > 1) {
$keys = array_rand($letters, 2);
shuffle($keys);
$result['paired'][] = $keys[0] . $keys[1];
--$letters[$keys[0]];
--$letters[$keys[1]];
$letters = array_filter($letters);
}
$result['unpaired'] = $letters;
return $result;
}