我有以下代码:
$json = json_decode(URL, true);
foreach($json as $var)
{
if($var[id] == $valdefined)
{
$number = $var[count];
}
}
使用json看起来像这样:
[{"id":"1","count":"77937"},
{"id":"2","count":"20"},
{"id":"4","count":"25"},
{"id":"5","count":"11365"}]
这是jsondecode
之后的数组($ json) Array ( [0] => Array ( [id] => 1 [count] => 77937 ) [1] => Array ( [id] => 2 [count] => 20 ) [2] => Array ( [id] => 4 [count] => 25 ) [3] => Array ( [id] => 5 [count] => 11365) )
有没有办法说出什么是$ json [count]其中$ json [id] = 3例如
答案 0 :(得分:0)
我不确定更好的方法,但这也没关系,只要JSON对象不大。在循环使用JSON时,php非常快。如果对象很大,那么您可能想要拆分它。我个人做的是将我的JSON变成普通对象的数组,对它们进行排序,然后在排序的项目上搜索更快。
修改强>
json_decode($your_thing, true);
设置为true是否为关联数组,然后id为 key ,计数为 value 。执行此操作后,使用ID获取值应该非常简单且效率更高。
答案 1 :(得分:0)
如果您将构建json对象的方式更改为如下所示: -
{"1":77937,"2":20,"4":25,"5":11365}
然后使用设置为TRUE的json_decode()参数2,即将json转换为数组。
然后你有一个可用的关联数组,其ID为关键字,如下所示:
<?php
$json = '{"1":77937,"2":20,"4":25,"5":11365}';
$json_array = json_decode($json, TRUE);
print_r( $json_array);
?>
导致此数组
Array
(
[1] => 77937
[2] => 20
[4] => 25
[5] => 11365
)
你可以做一个简单的
$number = json_array( $valdefined );
或者更好
if ( array_key_exists( $valdefined, $json_array ) ) {
$number = json_array( $valdefined );
} else {
$number = NULL; // or whatever value indicates its NON-EXISTANCE
}
答案 2 :(得分:0)
对您的初始问题的简短回答:为什么您不能写$json['count'] where $json['id'] = 3
?仅仅因为PHP不是查询语言。你提出问题的方式就像一个简单的SQL选择查询。 SQL将遍历其索引,并且(如果需要)将执行全表扫描,其结构化查询语言仅使您不能够写出循环DB 将执行。
不是这样,因为你没有写一个循环,没有循环(没有证据不是缺席的证据)。我不会全力以赴你,但我们可以在机器级别做很多事情。在较低级别,您只需要一步一步。通常,这意味着再次递增,检查和递增...... AKA递归和遍历
PHP将认为它理解$json['id']
的含义,并且它认为你的意思是它返回数组{{id
引用的值。 1}},而你实际上想要获取$json
。要确定$json[n]['id']
,您必须编写一个循环。有人建议对数组进行排序。这也就像映射/过滤/合并的任何其他n
函数一样,意味着循环整个数组。只有没办法。由于没有开箱即用的核心功能可以完全满足您的需要,因此您将不得不自己编写循环。
如果性能对您很重要,那么可以编写更有效的循环。下面,你可以找到一个稍微不那么粗暴的循环,一个半Interpolation search。你也可以在这里使用ternary search,实现你可以使用的东西。
array_*
for ($i = 1, $j = count($bar), $h = round($j/2);$i<$j;$i+= $h)
{
if ($bar[++$i]->id === $search || $bar[--$i]->id === $search || $bar[--$i]->id === $search)
{//thans to short-circuit evaluation, we can check 3 offsets in one go
$found = $bar[$i];
break;
}//++$i, --$i, --$i ==> $i === $i -1, increment again:
if ($bar[++$i]->id > $search)
{// too far
$i -= $h;//return to previous offset, step will be halved
}
else
{//not far enough
$h = $j - $i;//set step the remaining length, will be halved
}
$h = round($h/2);//halve step, and round, in case $h%2 === 1
//optional:
if(($i + $h + 1) === $j)
{//avoid overflow
$h -= 1;
}
}
是你的json解码数组
下面将解释这种工作原理的正确性,以及此方法的缺点,但就目前而言,与您的问题更相关:如何实施:
$bar
就个人而言,如果找不到属性 - 值对,我不会返回默认对象,我会返回function lookup(array $arr, $p, $val)
{
$j = count($arr);
if ($arr[$j-1]->{$p} < $val)
{//highest id is still less value is still less than $val:
return (object) array($p => $val, 'count' => 0, 'error' => 'out of bounds');
}
if ($arr[$j-1]->{$p} === $val)
{//the last element is the one we're looking for?
return $end;
}
if ($arr[0]->{$p} > $val)
{//the lowest value is still higher than the requested value?
return (object) array($p => $val, 'count' => 0, 'error' => 'underflow');
}
for ($i = 1, $h = round($j/2);$i<$j;$i+= $h)
{
if ($arr[++$i]->{$p} === $val || $arr[--$i]->{$p} === $val || $arr[--$i]->{$p} === $val)
{//checks offsets 2, 1, 0 respectively on first iteration
return $arr[$i];
}
if ($arr[$i++]->{$p} < $val && $arr[$i]->{$p} > $val)
{//requested value is in between? don't bother, it won't exist, then
return (object)array($p => $val, 'count' => 0, 'error' => 'does not exist');
}
if ($arr[++$i]->{$p} > $val)
{
$i -= $h;
}
else
{
$h = ($j - $i);
}
$h = round($h/2);
}
}
$count = lookup($json, 'id', 3);
echo $count['count'];
//or if you have the latest version of php
$count = (lookup($json, 'id', 3))['count'];//you'll have to return default value for this one
或抛出null
,但这是由你来决定的
循环基本上是这样的:
RuntimeException
,$i
和$i+1
处的对象。$i-1
,并且循环结束$found
中减去步骤($h
),并将该步骤减半。再次循环图表将说明为什么这是一种更“聪明”的循环方式:
$i
我们已经设法在仅仅3次迭代后找到了我们需要的对象,而不是11次迭代!虽然这个循环有点贵(涉及更多的计算),但缺点很少超过其好处
尽管如此,这个循环有一些盲点,所以在极少数情况下它会更慢,但平均来说它表现得相当不错。我已经测试了这个循环几次,一个包含100,000个对象的数组,寻找id |==========x=============================|//suppose x is what we need, offset 11 of a total length 40:
//iteration 1:
012 //checked offsets, not found
|==========x=============================|
//offset + 40/2 == 21
//iteration 2:
012//offsets 20, 21 and 22, not found, too far
|==========x=============================|
//offset - 21 + round(21/2)~>11 === 12
//iteration 3:
123 //checks offsets 11, 12, 13) ==> FOUND
|==========x=============================|
assign offset-1
break;
,我没有看到它花费的时间比.08ms多,平均而言,它管理的是.0018ms,这是一点也不差。
当然,您可以通过使用偏移处的id与搜索到的id之间的差异来改进循环,如果偏移random(1,99999)
处的id大于搜索值且偏移{{1小于搜索值以避免无限循环。但总的来说,这是目前为止提供的最具扩展性和高性能的循环算法。