在关联数组中查找范围
Find a range in associative arrays
我正在尝试从关联数组中找到一个范围。
数据来自 Racelogic(汽车性能 GPS 盒),所以我特别想从数组中提取 0-100。
可在此处找到完整数组:link
看起来像这样 (sats,time,lat,long,velocity,heading,height,vert-vel,yaw-calc,slip,YAW__,YAW_,):
Array
(
[31] => Array
(
[0] => 006
[1] => 194300,70
[2] => +03560,94626
[3] => -01079,53898
[4] => 009,490
[5] => 000,00
[6] => +00048,59
[7] => -000,432
[8] => +000,0
[9] => +0,00000E+00
[10] => +0,00000E+00
[11] => +0,00000E+00
[12] =>
)
[32] => Array
(
[0] => 005
[1] => 194300,80
[2] => +03560,94660
[3] => -01079,53760
[4] => 008,630
[5] => 259,90
[6] => +00050,46
[7] => -000,180
[8] => +000,0
[9] => +0,00000E+00
[10] => +0,00000E+00
[11] => +0,00000E+00
[12] =>
)
)
等等。在这种情况下,“4”是速度。
数据可以包含许多 0-100 运行,我想提取它们。我如何保存数据并不重要,可以是数组或字符串。
速度值永远不会准确地达到“100,000”,所以当它超过时需要,但是范围应该始终从“000,000”开始。
我在 PHP 方面相当不错,但是这个 logic/algorithm 让我头晕目眩了一段时间。非常感谢任何帮助或建议。
编辑:抱歉有点不明确,你自己的头脑总是更清楚。
数组包含速度数据,我想提取加速度 运行s,特别是 0-100。目前数据中有几个0-100 运行。这意味着我不仅想要最小值和最大值,我还想要每个 运行 的 0-100 之间的所有数据。我的最终目标是保存范围并使用 D3.js 播放它们,并在不同的汽车之间进行比较。
一种非常繁重的方法是按速度对整个数据集进行排序:
$data_sorted = usort($data, function($a, $b) {
return $a[4] < $b[4];
});
另一种方法是先使用 array_column
将速度提取到自己的数组中:
$velocities = array_column($data, 4);
然后使用 min() 和 max(),或 sort() 来获取最小值和最大值。
第三次尝试是只使用一个循环和 2 个 运行 变量。
$max = 0.0; $min = 100.0;
foreach ($data as $set) {
$max = max($max, $set[4]);
$min = min($min, $set[4]);
}
澄清之后,我重新阅读了你的问题并写了一些应该找到数据中所有"runs"的东西。
演示:http://codepad.viper-7.com/NSNJ0L
<?php
$data = array(
array('001', '194300,70', '+03560,94626', '-01079,53898', '109,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('002', '194300,70', '+03560,94626', '-01079,53898', '209,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('003', '194300,70', '+03560,94626', '-01079,53898', '009,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('004', '194300,70', '+03560,94626', '-01079,53898', '039,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('005', '194300,70', '+03560,94626', '-01079,53898', '069,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('006', '194300,70', '+03560,94626', '-01079,53898', '099,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('007', '194300,70', '+03560,94626', '-01079,53898', '109,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('008', '194300,80', '+03560,94660', '-01079,53760', '128,630', '259,90', '+00050,46', '-000,180', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('009', '194300,70', '+03560,94626', '-01079,53898', '001,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('010', '194300,70', '+03560,94626', '-01079,53898', '051,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('011', '194300,70', '+03560,94626', '-01079,53898', '101,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('012', '194300,70', '+03560,94626', '-01079,53898', '019,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
);
$targetColumn = 4;
$minValue = 0;
$maxValue = 100;
$found = false;
$filtered = array();
$run = 0;
foreach($data as $row){
//get our target value
$val = $row[$targetColumn];
//parse it as a number
$val = floatval(str_replace(',', '.', $val));
//if not found yet and our value is between the min and max, mark as found
if(!$found && ($val >= $minValue && $val <= $maxValue)){
$found = true;
}
//if found, add this value to the filtered array
if($found){
$filtered[$run][] = $row;
//if our value is over the max, increment our run and reset found
if($val > $maxValue){
$run++;
$found = false;
}
}
}
echo '<pre>'.print_r($filtered, true);
我正在尝试从关联数组中找到一个范围。 数据来自 Racelogic(汽车性能 GPS 盒),所以我特别想从数组中提取 0-100。
可在此处找到完整数组:link
看起来像这样 (sats,time,lat,long,velocity,heading,height,vert-vel,yaw-calc,slip,YAW__,YAW_,):
Array
(
[31] => Array
(
[0] => 006
[1] => 194300,70
[2] => +03560,94626
[3] => -01079,53898
[4] => 009,490
[5] => 000,00
[6] => +00048,59
[7] => -000,432
[8] => +000,0
[9] => +0,00000E+00
[10] => +0,00000E+00
[11] => +0,00000E+00
[12] =>
)
[32] => Array
(
[0] => 005
[1] => 194300,80
[2] => +03560,94660
[3] => -01079,53760
[4] => 008,630
[5] => 259,90
[6] => +00050,46
[7] => -000,180
[8] => +000,0
[9] => +0,00000E+00
[10] => +0,00000E+00
[11] => +0,00000E+00
[12] =>
)
)
等等。在这种情况下,“4”是速度。 数据可以包含许多 0-100 运行,我想提取它们。我如何保存数据并不重要,可以是数组或字符串。 速度值永远不会准确地达到“100,000”,所以当它超过时需要,但是范围应该始终从“000,000”开始。
我在 PHP 方面相当不错,但是这个 logic/algorithm 让我头晕目眩了一段时间。非常感谢任何帮助或建议。
编辑:抱歉有点不明确,你自己的头脑总是更清楚。 数组包含速度数据,我想提取加速度 运行s,特别是 0-100。目前数据中有几个0-100 运行。这意味着我不仅想要最小值和最大值,我还想要每个 运行 的 0-100 之间的所有数据。我的最终目标是保存范围并使用 D3.js 播放它们,并在不同的汽车之间进行比较。
一种非常繁重的方法是按速度对整个数据集进行排序:
$data_sorted = usort($data, function($a, $b) {
return $a[4] < $b[4];
});
另一种方法是先使用 array_column
将速度提取到自己的数组中:
$velocities = array_column($data, 4);
然后使用 min() 和 max(),或 sort() 来获取最小值和最大值。
第三次尝试是只使用一个循环和 2 个 运行 变量。
$max = 0.0; $min = 100.0;
foreach ($data as $set) {
$max = max($max, $set[4]);
$min = min($min, $set[4]);
}
澄清之后,我重新阅读了你的问题并写了一些应该找到数据中所有"runs"的东西。
演示:http://codepad.viper-7.com/NSNJ0L
<?php
$data = array(
array('001', '194300,70', '+03560,94626', '-01079,53898', '109,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('002', '194300,70', '+03560,94626', '-01079,53898', '209,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('003', '194300,70', '+03560,94626', '-01079,53898', '009,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('004', '194300,70', '+03560,94626', '-01079,53898', '039,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('005', '194300,70', '+03560,94626', '-01079,53898', '069,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('006', '194300,70', '+03560,94626', '-01079,53898', '099,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('007', '194300,70', '+03560,94626', '-01079,53898', '109,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('008', '194300,80', '+03560,94660', '-01079,53760', '128,630', '259,90', '+00050,46', '-000,180', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('009', '194300,70', '+03560,94626', '-01079,53898', '001,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('010', '194300,70', '+03560,94626', '-01079,53898', '051,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('011', '194300,70', '+03560,94626', '-01079,53898', '101,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
array('012', '194300,70', '+03560,94626', '-01079,53898', '019,490', '000,00', '+00048,59', '-000,432', '+000,0', '+0,00000E+00', '+0,00000E+00', '+0,00000E+00', '', ),
);
$targetColumn = 4;
$minValue = 0;
$maxValue = 100;
$found = false;
$filtered = array();
$run = 0;
foreach($data as $row){
//get our target value
$val = $row[$targetColumn];
//parse it as a number
$val = floatval(str_replace(',', '.', $val));
//if not found yet and our value is between the min and max, mark as found
if(!$found && ($val >= $minValue && $val <= $maxValue)){
$found = true;
}
//if found, add this value to the filtered array
if($found){
$filtered[$run][] = $row;
//if our value is over the max, increment our run and reset found
if($val > $maxValue){
$run++;
$found = false;
}
}
}
echo '<pre>'.print_r($filtered, true);