通过链接导航多个对象而不重复

2024-06-19

我正在尝试浏览一堆带有其他对象链接的对象。我想从 id 1 开始并浏览每个对象。有些对象会循环回到之前的对象,所以我想确保每个对象只查看一次,否则我会陷入无限循环。我还希望能够通过链接导航来判断哪些对象无法访问。我认为导航顺序并不重要。

这是我可能遇到的示例数据集(我的实际数据将来自数据库):

<?php

$obj_array = [] ;

$obj = new stdClass;
$obj->id = 1;
$obj->name = "Apple";
$obj->link = array(14, 5);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 3;
$obj->name = "Carrot";
$obj->link = array(1, 14, 3);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 4;
$obj->name = "Dill";
$obj->link = array(1, 5);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 5;
$obj->name = "Egg";
$obj->link = array(6);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 6;
$obj->name = "Fred";
$obj->link = array(7);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 7;
$obj->name = "Goat";
$obj->link = array(7, 8);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 8;
$obj->name = "Harry";
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 9;
$obj->name = "Igloo";
$obj->link = array(14, 5);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 10;
$obj->name = "Jason";
$obj->link = array(1, 5, 8);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 11;
$obj->name = "Klaus";
$obj->link = array(1, 5, 10);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 14;
$obj->name = "Banana";
$obj->link = array(3);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 15;
$obj->name = "Oyster1";
$obj->link = array(16);
$obj_array[] = $obj;


$obj = new stdClass;
$obj->id = 16;
$obj->name = "Oyster2";
$obj->link = array(15);
$obj_array[] = $obj;

我希望看到这样的东西(顺序无关紧要):

处理:

Apple
Banana
Carrot
Egg
Fred
Goat
Harry

未链接:

Dill
Igloo
Jason
Klaus
Oyster1
Oyster2

如何创建一个循环来遍历这样的结构,特别是当每个对象可以有多个链接时?


虽然@巫师回答 https://stackoverflow.com/a/45926587/434949工作了,我觉得我想要制作一个代码更清晰的版本。下面的版本返回一个带有链接和无内衬元素的对象,我相信它是如何工作的非常清楚。

我想这样工作的原因是能够将其扩展以解决未来的问题。例如“某个项目链接了多少次”或“哪个链接最多”。它也可以很容易地适应来回答这些问题。

另一个好处是它使用尽可能有限的循环,当大小增加时,这可以大大加快速度。

<?php
error_reporting(E_ALL);

$obj_array = [] ;

$obj = new stdClass;
$obj->id = 1;
$obj->name = "Apple";
$obj->link = array(14, 5);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 3;
$obj->name = "Carrot";
$obj->link = array(1, 14, 3);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 4;
$obj->name = "Dill";
$obj->link = array(1, 5);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 5;
$obj->name = "Egg";
$obj->link = array(6);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 6;
$obj->name = "Fred";
$obj->link = array(7);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 7;
$obj->name = "Goat";
$obj->link = array(7, 8);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 8;
$obj->name = "Harry";
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 9;
$obj->name = "Igloo";
$obj->link = array(14, 5);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 10;
$obj->name = "Jason";
$obj->link = array(1, 5, 8);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 11;
$obj->name = "Klaus";
$obj->link = array(1, 5, 10);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 14;
$obj->name = "Banana";
$obj->link = array(3);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 15;
$obj->name = "Oyster1";
$obj->link = array(16);
$obj_array[] = $obj;

$obj = new stdClass;
$obj->id = 16;
$obj->name = "Oyster2";
$obj->link = array(15);
$obj_array[] = $obj;


/*
 * CALL
 */

$parser = new ObjectLinker($obj_array, 1);

//dump found
//decode/encode to only show public values
print_r(json_decode(json_encode($parser)));


/*
 * ACTUAL CODE
 */


class ObjectLinker
{
    private $_array;
    private $_start;

    public $LinkedElements = array();
    public $UnLinkedElements = array();

    final public function __construct($ar, $start)
    {
        $this->_array = $ar;
        $this->_start = $start;

        $this->getElementsArray();
        $this->findLinked($this->_start);
    }

    final private function getElementsArray()
    {       
            //since each Id is unique, i'm using the ID as the key in the array. this will allow faster access
            //Ofcourse it would be better if you would create the array like this in the first place, then you can skip this step
            foreach($this->_array as $obj) {
                if (!is_null($obj) && property_exists($obj, 'id')) {
                    //I add everything to the unlinked elements. We will remove the linked once, to have once less loop
                    $this->UnLinkedElements[$obj->id] = $obj;
                }
            }
    }


    final private function findLinked($id)
    {
        //If the key is not in the array, it's already loaded
        if (!array_key_exists($id, $this->UnLinkedElements)) {
            return;
        }

        //get obj
        //Because of the getElementsArray() step, I'm already sure the object exists.
        //If you change the input array, you might want to check for invalid obj
        $obj = $this->UnLinkedElements[$id];

        //add to linked
        $this->LinkedElements[$id] = $obj;

        //remove from unlinked
        unset($this->UnLinkedElements[$id]);

        //no links
        if (!property_exists($obj, 'link')) {
            return;
        }

        $links = $obj->link;

        //Invalid links
        if (!is_array($links)) {
            return;
        }

        //check links
        foreach($links as $link) {
            $this->findLinked($link);
        }
    }

}

?>

Output:

stdClass Object
(
  [LinkedElements] => stdClass Object
    (
      [1] => stdClass Object
        (
          [id] => 1
          [name] => Apple
          [link] => Array
            (
              [0] => 14
              [1] => 5
            )

        )

      [14] => stdClass Object
        (
          [id] => 14
          [name] => Banana
          [link] => Array
            (
              [0] => 3
            )

        )

      [3] => stdClass Object
        (
          [id] => 3
          [name] => Carrot
          [link] => Array
            (
              [0] => 1
              [1] => 14
              [2] => 3
            )

        )

      [5] => stdClass Object
        (
          [id] => 5
          [name] => Egg
          [link] => Array
            (
              [0] => 6
            )

        )

      [6] => stdClass Object
        (
          [id] => 6
          [name] => Fred
          [link] => Array
            (
              [0] => 7
            )

        )

      [7] => stdClass Object
        (
          [id] => 7
          [name] => Goat
          [link] => Array
            (
              [0] => 7
              [1] => 8
            )

        )

      [8] => stdClass Object
        (
          [id] => 8
          [name] => Harry
        )

    )

  [UnLinkedElements] => stdClass Object
    (
      [4] => stdClass Object
        (
          [id] => 4
          [name] => Dill
          [link] => Array
            (
              [0] => 1
              [1] => 5
            )

        )

      [9] => stdClass Object
        (
          [id] => 9
          [name] => Igloo
          [link] => Array
            (
              [0] => 14
              [1] => 5
            )

        )

      [10] => stdClass Object
        (
          [id] => 10
          [name] => Jason
          [link] => Array
            (
              [0] => 1
              [1] => 5
              [2] => 8
            )

        )

      [11] => stdClass Object
        (
          [id] => 11
          [name] => Klaus
          [link] => Array
            (
              [0] => 1
              [1] => 5
              [2] => 10
            )

        )

      [15] => stdClass Object
        (
          [id] => 15
          [name] => Oyster1
          [link] => Array
            (
              [0] => 16
            )

        )

      [16] => stdClass Object
        (
          [id] => 16
          [name] => Oyster2
          [link] => Array
            (
              [0] => 15
            )

        )

    )

)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过链接导航多个对象而不重复 的相关文章

  • mysql - 如果日期不与现有日期重叠,则将日期范围插入日期列

    我有以下表结构 表名 available id autoincremetn acc id start date end date 1 175 2015 05 26 2015 05 31 2 175 2015 07 01 2015 07 07
  • 升级 PHP 本地实现的 Olson tz 数据库

    我正在开发一个大量使用时区的网站 该网站需要处于可用的绝对最新 tz 信息的最前沿 我已经通过tz 邮件列表 http news gmane org gmane comp time tz 我不知道的是如何让 PHP 安装在我的开发计算机和
  • PHP 难以检查数组中的元素是否为整数类型

    我正在尝试检测一个或多个变量是否包含数字 我尝试了几种不同的方法 但并没有完全成功 这是我尝试过的
  • mysql utf8_general_ci 区分大小写

    我有一个 mysql 数据库 我使用 utf8 general ci 不区分大小写 在我的表中 我有一些列 例如 ID 和区分大小写的数据 例如 iSZ6fX 或 AscSc2 为了区分大写和小写 最好只在这些列上设置 utf8 bin 如
  • PHP 数组按月和总和分组

    我有一个 php 数组 如第一张图片所示 我想要的只是按月获取值的总和 如下所示 我知道这对我们大多数人来说可能很容易 但说实话 我找不到可行的方法来实现它 我尝试在谷歌上搜索 但我找到的所有结果都是关于对数据库查询结果进行分组和求和 而对
  • PHPUnit 测试套件包含路径

    使用 phpunit 时 我在包含路径方面遇到了一些麻烦 不是针对 phpunit 本身 而是针对我的代码和测试目录 我有以下代码结构 Application StringCalculator php tests StringCalcula
  • magento 中的自动发票

    我创建了新的自定义产品类型 它扩展了 magento 中的虚拟产品 现在我想阻止在线支付的自动发票 例如 当订单包含至少一种自定义产品类型时 使用 Paypal 所有包含此类产品的订单都必须手动开具发票 我应该如何解决这个问题 最好的方法是
  • 如何获取发送的 PHP 卷曲请求的信息

    我正在尝试调试对 Web 服务 getToken 端点的curl 请求 我不能 100 确信 URL 和身份验证信息已正确写入curl 句柄 我正在尝试使用curl getinfo ch CURLINFO HEADER OUT 捕获发送的请
  • 如何在打字稿中将枚举转换为键、值数组?

    var enums 1 HELLO 2 BYE 3 TATA 我希望能够将其转换为如下所示的数组 number 1 word HELLO number 2 word BYE number 3 word TATA 我看到的所有解决方案都形成一
  • 使用 SFTP 上传文件

    我已成功通过 ftp 上传文件 但现在需要通过 SFTP 上传 我可以成功连接到远程服务器 创建文件并写入文件 但无法将现有文件从本地服务器上传到远程服务器 ftp put 没有通过 sftp 连接触发吗 我的代码用来编写一个文件 Send
  • php洗一副牌

    我想使用 php 创建随机桥手的集合 我认为我可以将有序的卡片包编码为字符串 deal下面 我喜欢它有 52 个字母 同时考虑大小写 我发现了 php 函数str shuffle 所以我想我可以做以下事情 pack abcdefghijkl
  • 在 Laravel 5 中合并 'with' 和 'whereHas'

    我在 Laravel 5 中使用 Eloquent 编写了这段代码 它工作得很好 filterTask function query use id query gt where taskid id User whereHas submiss
  • 原则 2 使用 QueryBuilder 进行条件多行更新

    这个问题有一些答案 但实际上 它们似乎都无法帮助完成一项简单的任务 我需要使用 Doctrine2 QueryBuilder 根据一个查询中的条件更新多行 最明显的方法应该是错误的 userAgeList user name a gt 30
  • 如何在聚合框架中按位置修改数组中的值

    假设有一个简单的文档 array a b c d 如何修改second值在聚合 With update这很简单 db collection updateOne set array 1 B gives array a B c d 在聚合框架中
  • 将父产品名称添加到 WooCommerce 中的每个购物车项目名称中

    我想在购物车页面中显示父产品名称和子产品名称 购物车项目 以供我使用分组产品 我在链接产品 gt 添加子产品的分组产品下选择父产品数据作为分组产品 模板中的代码cart php echo apply filters woocommerce
  • PHP exec() 返回值是什么?

    我正在尝试使用 PHP exec 函数 如果 return var 参数与输出参数一起存在 那么执行命令的返回状态将被写入此 多变的 如果执行成功 则为 0 但是 如果出现错误 则可能是多个其他整数 我似乎无法在任何地方找到这些整数对应的内
  • 使用 MongoDB PHP 驱动程序时的安全问题

    我有在 MYSQL 上保护 sql 注入的经验 但是在使用 php 驱动程序的 MongoDB 上我应该注意什么 在大多数页面中 我通过 GET POST 和搜索 插入系统获取数据 我通过 UDID 其他字段进行搜索 并且可以插入任何字符串
  • 通过 Laravel 框架集成现有项目?

    我已经从 github 克隆了一个项目 现在我需要集成该项目 那么如何使用 laravel 框架 我是否需要创建一个新项目然后需要替换文件夹 或任何其他替代方案 因为我是这个框架的新手 帮助我 这是一个广泛的问题 因为这取决于您的项目 而我
  • 客户端与服务器端图像压缩[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在研究用户可以上传图片的东西 图像大小不受限制 现在我有两个选择使用PHP 服务器端 压缩图像或使用
  • 为什么我不能分配 const 但我可以控制台记录它?

    我做了一些java脚本练习 让几个链接按字母顺序排列 这是 HTML a href a is good a a href c is good a a href b is good a JavaScript const allhref doc

随机推荐

  • Spinner onItemSelected 被错误调用(无需用户操作)

    我有一个在对话框视图中显示的微调器 对话框开始时onItemSelected叫做 我真的不想处理这个 但只有当用户做出选择时 所以我要么需要阻止这种情况 也许是因为没有设置默认值 要么我需要知道不是用户在做出此选择 本着比尔 莫特解决方案的
  • Android:如何在 Android 中访问电子邮件地址

    我有以下代码 通过它我可以检索电话号码 不知何故 我无法使用 android provider Contacts People API 检索电子邮件地址 有任何想法吗 import android app AlertDialog impor
  • 带填充的 Tailwind CSS 导航悬停下拉菜单

    我正在尝试展示子 ul 当项目悬停时 在第一个导航项目上列出 一切正常 除了有时 时好时坏 当您位于第一行的填充之间时 ul 项目和子项目 ul 项目 次要项目 ul 会消失 当我从下拉菜单导航到项目列表时 如何保持辅助导航列表打开 JSF
  • 如何安装 grunt-cli 而不出现错误?

    灵感来自 Chris Coyierpost http 24ways org 2013 grunt is not weird and hard 我决定尝试一下 grunt 但我在设置时遇到了很大的问题 首先 我安装了 Node js 然后我将
  • 使用 BinaryWriter 将一位写入二进制文件

    我想将一位写入二进制文件 using FileStream fileStream new FileStream myfile bin FileMode Create using BinaryWriter binaryWriter new B
  • 无法在 IBM Mobilefirst Platform Test Workbench 8.7(免费版本)中引用数据池测试

    使用的工具 IBM Mobilefirst Platform Test Workbench 8 7 免费版 OS Windows 7的 问题描述 1 在测试工作台中以记录模式创建测试用例 针对登录场景 2 插入一个新的数据池 并向数据池中的
  • 模拟比存根更好吗?

    不久前我读到了模拟不是存根 http www martinfowler com articles mocksArentStubs htmlMartin Fowler 的文章 我必须承认我有点害怕外部依赖性增加的复杂性 所以我想问 单元测试时
  • 如何解决下载时“失败 - 无文件”的问题?

    我正在尝试设置适用于 Chrome 和 IE 10 11 的下载文件 它在大多数情况下适用于普通文件类型 EXE PNG TXT 等 但当尝试下载没有文件类型的文本文件或 000 等随机类型时 它将失败 显示 失败 否 文件 有谁知道可能导
  • 扩展 Protobuf 消息

    我有许多不同的模式 但是每个模式都包含一组字段 我想知道是否有一种方法可以让不同的模式扩展父模式并继承其字段 例如 这就是我想要的 message Parent required string common1 0 optional stri
  • 多个 MapFragment 的性能(Android Map API v2)

    我搜索了新的文档谷歌 Android 地图 API v2 https developers google com maps documentation android 但没有找到任何相关信息 在 v2 之前 我们 官方 无法正确显示每个应用
  • Ubuntu 中的颜色选择器实用程序(颜色移液器)[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用脚本从网站中提取电子邮件地址

    给定一个网站 我想知道以编程方式和 或使用脚本的最佳程序是什么 以纯文本形式提取每个页面上存在的所有电子邮件地址 电子邮件受保护 cdn cgi l email protection从该链接和下面的所有站点 递归或直到某个固定深度 使用 s
  • 在网站上不间断地播放 mp3?

    客户请求在整个网站上播放单个曲目 一般来说 我建议不要这样做 但他们坚持这样做 那么 将 Flash 播放器嵌入到网站中并且当用户转到另一个页面时不会出现间隙 中断的最直接方法是什么 我认为需要一个 iframe 我正在使用具有自动恢复功能
  • iPhone OS:从匿名对象获取方法和变量列表

    我正在构建我的第一个 iPhone Obj c 应用程序 并且我有大量的数据保存子类 我将它们传递给引用函数 对于 cite 函数 这些对象是匿名的 我需要找到一种方法来访问每个传递对象的所有变量 我一直在使用预构建的 NSArray 和选
  • 如何在 Ruby 中创建自定义排序方法

    我想指定一个自定义块方法 通过评估两个属性来对对象数组进行排序 然而 经过多次搜索 我没有找到任何没有的例子 lt gt 操作员 我想比较a to b if a x less than b x return 1 if a x greater
  • 密文窃取算法 - 哪一种是正确的?

    网络上提出了两种算法 在这两种算法中 第一部分是相同的 1 Pad the last partial plaintext block with 0 2 Encrypt the whole padded plaintext using the
  • AttributeError:“模块”对象没有属性“TestCase”

    我有名为 test py 的unittest 文件 My code import unittest class Test unittest TestCase def myTest self a 1 self assertEqual a 1
  • 将 std::stack .pop() 方法的结果存储到变量中

    我想做以下事情 std stack
  • MVC4 如何设置 cookie 然后重定向到操作

    您好 我正在尝试获取用户角色并将其设置为我的应用程序中的 cookie 我有以下有效的代码 public ActionResult Index var user User Identity Name set by 3rd party cen
  • 通过链接导航多个对象而不重复

    我正在尝试浏览一堆带有其他对象链接的对象 我想从 id 1 开始并浏览每个对象 有些对象会循环回到之前的对象 所以我想确保每个对象只查看一次 否则我会陷入无限循环 我还希望能够通过链接导航来判断哪些对象无法访问 我认为导航顺序并不重要 这是