Cây trong php

Là một nhà phát triển Drupal giỏi, một trong những mục tiêu trong năm mới của bạn là tìm hiểu thêm các tính năng của PHP. Hôm nay, chúng ta sẽ nói về việc lặp lại dữ liệu có cấu trúc cây bằng cách sử dụng lớp có tên khó hiểu là RecursiveIteratorIterator

Khi nói đến mảng, PHP có rất nhiều công cụ hữu ích mà bạn đã biết, chẳng hạn như
in_array, array_map và preg_grep. Nhưng còn cấu trúc cây thì sao? . thư mục trên hệ thống tệp của bạn, menu Drupal, thuật ngữ phân loại phân cấp, cây DOM, v.v. Bạn có thể xử lý chúng bằng các vòng lặp và đệ quy nhưng nó khá phức tạp—chỉ cần nhìn vào nguồn của file_scan_directory để biết ý tôi là gì. Sẽ không dễ dàng hơn nếu bạn chỉ có thể sử dụng các hàm mảng của PHP trên cây sao?

Chúng tôi sẽ sử dụng RecursiveIteratorIterator tích hợp để làm phẳng cấu trúc cây và làm cho chúng dễ xử lý hơn nhiều. Bạn chỉ cần cung cấp cho hàm tạo RecursiveIteratorIterator một RecursiveIterator, hàm này cho nó biết cách duyệt qua cây cụ thể đang được đề cập—ví dụ: RecursiveDirectoryIterator biết cách lặp lại vào các thư mục. Sau đó, bạn có thể lặp lại toàn bộ cấu trúc phân cấp chỉ trong một vòng lặp foreach đơn giản. Đây là một ví dụ

// Create a RecursiveIterator that knows how to follow subdirectories.
$recursive_iter = new RecursiveDirectoryIterator('.', FilesystemIterator::SKIP_DOTS);

// Pass the RecursiveIterator to the constructor of RecursiveIteratorIterator.
$recursive_iter_iter = new RecursiveIteratorIterator(
  $recursive_iter,
  // Also pass in a 'mode', to specify whether parents should come before children,
  // after children, or not at all. We want parents first, so we use SELF_FIRST.
  RecursiveIteratorIterator::SELF_FIRST
);

// Use our RecursiveIteratorIterator as if it was a flat array.
foreach ($recursive_iter_iter as $path => $info) {
  print "$path\n";
}

// Or process it with standard array functions!
$pngs = preg_grep('/\.png$/', iterator_to_array($recursive_iter_iter));
foreach ($pngs as $path => $info) {
  print "png: $path\n";
}

Menu trong Drupal cũng là cây và chúng có thể khá phức tạp để xử lý. Vì vậy, hãy thử sử dụng phương pháp tương tự như trên, nhưng lần này là cho các menu

Thật không may, không có RecursiveIterator tích hợp sẵn cho cây menu, như RecursiveDirectoryIterator là thư mục. Vì vậy, thay vào đó, chúng ta phải xây dựng của riêng mình, bằng cách phân lớp một trình vòng lặp hiện có và triển khai getChildren()hasChildren(). Đó là một chút công việc, nhưng sau đó chúng ta có thể dễ dàng xử lý một menu phân cấp hoàn chỉnh chỉ trong một vài dòng mã

current();
    return new MenuIterator($link_data['below']);
  }

  // Does this item have children?
  public function hasChildren() {
    $link_data = $this->current();
    return !empty($link_data['below']);
  }
}

// Now let's use our new class to print out a pretty list of menu items:

// Get a menu tree.
$menu = drush_get_option('menu');
$tree = menu_build_tree($menu);

// Create a MenuIterator over the tree.
$menu_iterator = new MenuIterator($tree);

// Create a RecursiveIteratorIterator, passing in our MenuIterator.
$recursive_iter_iter = new RecursiveIteratorIterator(
  $menu_iterator,
  RecursiveIteratorIterator::SELF_FIRST
);

// Iterate over the whole tree, as if it was flat.
foreach ($recursive_iter_iter` as $link_data) {
  $link = $link_data['link'];
  if ($link['hidden'] == 0) { // Ignore hidden items.
    $prefix = str_repeat('  ', $link['depth'] - 1); // Make our output pretty.
    printf("%-40s  %s\n", $prefix . $link['title'], $link['link_path']);
  }
}

Đây là một ví dụ về việc chạy tập lệnh này

$ drush --user=1 php-script menu-tree.php --menu=management
Administration                            admin
  Dashboard                               admin/dashboard
  Content                                 admin/content
    Comments                              admin/content/comment
  Structure                               admin/structure
    Blocks                                admin/structure/block
    Content types                         admin/structure/types
    Menus                                 admin/structure/menu
      Main menu                           admin/structure/menu/manage/main-menu
      Management                          admin/structure/menu/manage/management
      Navigation                          admin/structure/menu/manage/navigation
      User menu                           admin/structure/menu/manage/user-menu
    Taxonomy                              admin/structure/taxonomy
  Appearance                              admin/appearance
[snip]

Đây chỉ là đỉnh của tảng băng trôi. Có rất nhiều cây dữ liệu khác trên thế giới có thể được xử lý bằng RecursiveIteratorIterator. Các phần tử XML, , HTML và hơn thế nữa. Hãy cho chúng tôi biết những gì bạn tìm thấy cho RecursiveIteratorIterator

Làm cách nào để tạo một cây trong PHP?

Thuật toán khá đơn giản. .
Lấy mảng của tất cả các phần tử và id của cha mẹ hiện tại (ban đầu là 0/nothing/null/whatever)
Lặp qua tất cả các phần tử
Nếu parent_id của một phần tử khớp với id cha hiện tại mà bạn có trong 1. , phần tử là con của cha

cây trong kiểu dữ liệu là gì?

Cây là một loại cấu trúc dữ liệu biểu thị dữ liệu phân cấp . Nó có cấu trúc phi tuyến tính bao gồm các nút được kết nối bởi các cạnh. Trong số các loại cấu trúc dữ liệu khác thực hiện các hoạt động trong cấu trúc dữ liệu tuyến tính, webinarity phức tạp tăng lên khi tăng kích thước dữ liệu.

Làm cách nào để tạo cấu trúc cây nhị phân trong PHP?

Chúng ta có thể triển khai cây nhị phân bằng mảng PHP. Vì cây nhị phân có tối đa từ 0 đến hai nút con, chúng ta có thể sử dụng các nút con tối đa là 2 và xây dựng công thức để tìm các nút con của một nút đã cho. Let's number the nodes in a binary tree from top to bottom and left to right.

Cây trong mã hóa là gì?

Cây là tập hợp các nút được kết nối bởi các cạnh có hướng (hoặc vô hướng) . Cây là cấu trúc dữ liệu phi tuyến tính, so với mảng, danh sách liên kết, ngăn xếp và hàng đợi là cấu trúc dữ liệu tuyến tính.