在排序时保留JSON数组

10

我有两个来自外部网站的JSON数组。我先对这两个数组进行排序和合并,再解码并按ID从高到低排序。

目前,当单击“按字母顺序排序”选项时,在URL末尾添加?sort=alphabetical,页面加载完成后,JSON数组再次被解码并合并。

这不是我想要的结果:当单击该选项时,我不希望JSON数组再次被解码并合并 - 我只想要已经解码并合并的JSON数组按字母顺序排序。


数组:

$homepage = array();  

$homepage[]= '{  
   "info":{  
      "collection":[  
         {  
            "Name":"Charlie",
            "ID":"7"
         },
         {  
            "Name":"Emma",
            "ID":"9"
         }
      ]
   }
}';  

$homepage[] = '{  
   "info":{  
      "collection":[  
         {  
            "Name":"Bob",
            "ID":"5"
         }
      ]
   }
}';

排序:

$data = array();
foreach ($homepage as $homepage2) {
    $tmp=json_decode($homepage2, false);
    $data = array_merge($data,$tmp->info->collection);
}

if(!empty($_GET['sort']) && $_GET['sort'] == 'alphabetical') {
    usort($data, function ($a, $b) {
        return strcmp($a->Name, $b->Name);
    });
}else{
    usort($data, function ($a, $b) {
        return $b->ID - $a->ID;
    });
}

echo'
<select onchange="location.href = this.value;">
    <option value="example.php?sort=alphabetical">Alphabetical</option>
</select>
';

foreach($data as $key) {
    echo'
    <a href="test.com">
    <p>'.$key->ID.'</p>
    <p>'.$key->Name.'</p>
    </a>
    ';
}  

2
@TheCodesee 如果你想在不刷新页面的情况下更改页面内容,几乎肯定需要编写一些JavaScript代码来实现 - 除非你想创建另一个请求到服务器并替换页面内容。 - Patrick White
1
请问为什么您不想再次解码/合并JSON字符串数组呢?这不是一个很大的性能问题,避免这种情况的唯一方法是将解码/合并后的数据存储在某个地方(比如PHP会话或数据库), 但这似乎只会带来更多的问题。 - Sam
1
@Sam 很好的问题。正如我在帖子中提到的那样,我正在从外部URL获取JSON数据(我在这个问题中发布了一个JSON文件的示例,以便更容易理解)。我担心如果我发出太多请求,服务器会阻止我。 - The Codesee
1
你能否提供输出IDName值的确切方式?我不认为你只是这样输出它们而没有HTML。基于Javascript的解决方案需要知道你将它们放在哪个HTML结构中。 - trincot
有没有任何答案解决了你的问题?你可以留下评论或接受你选择的答案吗? - trincot
显示剩余6条评论
3个回答

5

您可以使用JavaScript来实现点击排序,并仅使用PHP将JSON传递给它。

在提供要显示列表的HTML结构后,我更新了此答案,使用

元素作为记录,使用

元素作为字段。

我们可以用两个按钮替换选择排序顺序的


非常感谢您的出色回复,我真的没有想到!对于我的问题没有表述清楚,我深表歉意。我不是在表格中显示结果,而是在一个div元素中显示它们。根据您的代码,我已经修改了它以适应我的需求:https://jsfiddle.net/jknj4uat/1/ (您能否更新您的帖子)- 非常感谢您的帮助 :) - The Codesee
我很乐意调整我的答案,但是你在问题中现在要求的HTML包括ap标签,而你指向的jsfiddle仅输出名称,而不是ID,并且没有这些ap标签。因此,在几乎所有方面都有所不同。你到底想要什么?;-) - trincot
无论如何,我已经更新了我的帖子。请注意,在涉及未格式化的文本时,最好使用textContent而不是innerHTML。我还使用了bind来创建两种populate函数的变体,现在它接受要排序的函数作为参数。 - trincot

2

这个问题有几种解决方案,我将提供一种简单的解决方案:

发送已经排序好的数据作为默认值,如果用户没有做出选择。然后,设置一个函数来根据需要对数据进行排序,并重新绘制表格/ divs/任何您用于呈现它们的内容。

以下是一个快速示例:

function sortAlpha(){
   for each (stuff in data){
      document.getElementById("aTable").textContent=data.StringRepresentation;
   }
}

接着是 sortSize、sortEtc 等函数...在每个函数中,你需要清空一个 div 的内容,然后再次填充它。这样,你就不需要向服务器请求新内容。

getElementById 文档


是的,JS是最好的解决方案(如果没有使用数据库来存储数据的话)。 - Sam

0

有多种解决方案可以实现所需的结果。

如果您想要使用纯PHP方式,您可以将数据保存在PHP会话中,并根据需要检索它们。

这里的诀窍是,您创建一个函数来获取结果数据,在其中传递单个参数,无论您是要从外部URL获取数据还是从已保存的数据中获取数据。

现在,在您的应用程序中,每当您想要刷新已保存的数据时,请使用参数调用相同的函数,表示要刷新在SESSIONS中保存的数据以替换来自外部源的数据。

使用此方法,您可以重复使用已从外部源获取的数据,而无需每次重新加载函数时重新获取它。

您可以编写另一个函数,该函数将对所有情况返回true,在这些情况下,应用程序必须从外部源重新获取结果集。

我为您编写了伪代码,以便您理解我试图传达的内容,

检查我们是否必须从外部源重新获取结果的函数:

function hasToRefreshResult() {
        if(/* CERTAIN CONDITIONS */) {
            return true;
        }
        return false;
    }

根据传递的参数,从本地/外部源获取数据的几个函数:

    function getResultArray($getdatafromlocal) {
        if(!hasToRefreshResult() && $getdatafromlocal && array_key_exists("filertereddata",$_SESSION) && isset($_SESSION["filertereddata"])) {
            $data=$_SESSION["filertereddata"];
        } else {
            $data=getDataFromExternalURL();
        }

        if(!empty($_GET['sort']) && $_GET['sort'] == 'alphabetical') {
            usort($data, function ($a, $b) {
                return strcmp($a->Name, $b->Name);
            });
        } else {
            usort($data, function ($a, $b) {
                return $b->ID - $a->ID;
            });
        }

        return $data;
    }

    function getDataFromExternalURL() {
        /*****
           YOUR LOGIC TO GET DATA FROM EXTERNAL URL;
         *****/

        $data = array();
        foreach ($homepage as $homepage2) {
            $tmp=json_decode($homepage2, false);
            $data = array_merge($data,$tmp->info->collection);
        }
        $_SESSION["filertereddata"]=$data;
        return $data;
    }

我希望这可以严格使用 PHP 解决你的问题。

同时,不要忘记在你将使用这些函数的 PHP 文件顶部写上 session_start();


请问一下,如果用户在不进行排序的情况下重新加载页面,它会解码并合并数组吗? - The Codesee
可以做到。只需调用函数以获取数据。当函数在会话中找不到数据时,它将从外部源获取数据。当它在会话中找到数据时,它将仅返回会话中的数据,您可以执行任何所需的排序。 - Alok Patel
根据您的要求,它不会执行多个对外部源的请求。 - Alok Patel
所以,如果$data为空的话 { - The Codesee
1
会话变量只应用于与用户相关或多个不相互连接组件所需的信息。将其用作数据转储场所非常糟糕的做法。 - Tony Chiboucas
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接