从php json中选择特定数据

时间:2013-08-12 13:56:03

标签: php json

我有以下代码:

$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例如

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,但这是由你来决定的


循环基本上是这样的:

  1. 在每次迭代时,检查偏移RuntimeException$i$i+1处的对象。
    如果找到该对象,则将对它的引用分配给$i-1,并且循环结束
  2. 找不到该对象。执行以下两个步骤中的任何一个:
    • 偏移处的ID大于我们要查找的ID,从偏移$found中减去步骤($h),并将该步骤减半。再次循环
    • ID小于搜索(我们还没有):将步长更改为数组剩余长度的一半
  3. 图表将说明为什么这是一种更“聪明”的循环方式:

    $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小于搜索值以避免无限循环。但总的来说,这是目前为止提供的最具扩展性和高性能的循环算法。

    Check the basic codepad in action here

    Codepad with loop wrapped in a function