我需要将两个PhP函数(sfGetCategoryAllTree和sfSideTree)转换为C#。我一点也不习惯博士。我将向您展示功能以及我现在所做的工作。
/**
* Retrieves user data given a user id or user object.
*
* @param string $output Optional, default is Object. Either OBJECT, ARRAY_A, or ARRAY_N.
* @return Category|null Category on success or null on failure
*/
function sfGetCategoryAllTree($output = OBJECT,$id='') {
global $sfdb, $table_category, $table_category_lang;
$categories = $sfdb->run("SELECT * FROM $table_category c"'
ORDER BY position ASC", '', true)
->fetchAll($output);
$all_categories = array();
$all_relation = array();
$tree = array();
foreach ($categories as $c) {
$all_categories[$c['id']] = $c;
if ($c['parent_id'] == null) {
$tree[] = $c;
$all_relation[0][] = $c['id'];
} else {
$all_relation[$c['parent_id']][] = $c['id'];
}
}
if (isset($all_relation[0])) {
$tree = sfSideTree($all_relation[0], $all_categories, $all_relation);
}
return ($tree) ? $tree : array();
}
/**
* Helps create the tree
*
* @param array $branch
* @param array $categories
* @param array $relation
* @return array
*/
function sfSideTree($branch, $categories, $relation) {
$tree = array();
if (!empty($branch)) {
foreach ($branch as $b) {
$aux = $categories[$b];
if (isset($relation[$b]) && is_array($relation[$b])) {
$aux['categories'] = sfSideTree($relation[$b], $categories, $relation);
} else {
$aux['categories'] = array();
}
$tree[] = $aux;
}
}
return $tree;
}
到目前为止我做了什么:
public void sfSideTree(int[] branch, Category[] categories, int[] relation)
{
Category[] tree = new Category[10];
foreach (var b in branch)
{
var aux = categories[b];
if (relation[b] != null)
{
aux[]....
}
}
}
public void sfGetCategoryAllTree()
{
var categories = this.Query().Select().ToList();
/*
$all_categories = array();
$all_relation = array();
$tree = array();
*/
//IList<Category> all_categories = new List<Category>();
//IList<Category> all_relation = new List<Category>();
//IList<Category> tree = new List<Category>();
Category[] all_categories = new Category[10];
int[] all_relation = new int[10];
Category[] tree = new Category[10];
foreach (var c in categories)
{
//$all_categories[$c['id']] = $c;
all_categories[c.Id] = c;
//all_categories.Add(new Category() { Id = item.Id });
if (c.ParentId == 0)
{
tree[??] = c; //???
all_relation[0] = c.Id;
/*
$tree[] = $c;
$all_relation[0][] = $c['id'];*/
}
else
{
all_relation[c.ParentId] = c.Id;
//$all_relation[$c['parent_id']][] = $c['id'];
}
}
if (all_relation != null)
{
sfSideTree(all_relation[0], all_categories, all_relation);
}
return tree;
/*return ($tree) ? $tree: array();*/
}
PhP数组使翻译变得更加困难。有人能帮我吗?
David
编辑
在这里回答OwlSolo分类类的结构
public class Category
{
public int Id { get; set; }
public int ParentId { get; set; }
public int Position { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool Enabled { get; set; }
}
根据您对我上一个答案的评论,这就是我在C#中实现的方式:
public void makeTree()
{
//Make a Dictionary with the ID als key
Dictionary<int, Category> categories = this.Query().Select().ToDictionary(a => a.ID, a => a);
foreach (Category c in categories)
{
if (c.ParentID != 0)
{
if (categories[c.ParentID].children == null)
{
categories[c.ParentID].children = new List<Category>();
}
categories[c.ParentID].children.add(c);
}//ParentID == 0 means its a root element
}
}
这只是从您的查询中创建一个树结构。如果需要展开"类别",只需访问其子项列表即可。除非我忽略了什么,否则这才是你真正想在这里做的。不需要保留单独的列表或其他杂乱的方法来遍历树。
如果你想列出所有根目录,只需点击:
public List<Category> getRootNodes()
{
List<Category> rootNodes = new List<Category>();
foreach (Category c in categories)
{
if (c.ParentID == 0) rootNodes.Add(c);
}
return rootNodes;
}
EDIT刚刚意识到最后一个函数非常不成功,因为使用linq可以更容易地完成
rootNodes = catergories.Where(x => x.ParentID == 0);
PHP数组与C#类型并不是100%兼容,但您可以通过使用大量Dictionary来解决这一问题,例如,PHP允许您通过int或string等同物来寻址字段类型。这当然不是最好的做法,但到目前为止,还不清楚你实际存储的数据是什么。我尝试了一下,但它可能无法开箱即用。根据实际数据,可能需要进行一些调整。
EDIT:为了使其成为一棵树,Category类还需要一种引用其子级的方法——在PHP中,这是通过["categories"]字段实现的。
class Category
{
[...]
IList<Category> children;
}
//For instance as global arrays...
int[] all_categories;
int[] all_relation;
List<Category> sfGetCategoryAllTree(output, id)
{
List<Category> tree;
//$categories = $sfdb->run("SELECT * FROM $table_category c"'
// ORDER BY position ASC", '', true)
// ->fetchAll($output);
List<Category> categories = this.Query().Select().ToList();// Assuming this is aquivalent to the above selection statement...
foreach (Category c in categories)
{
all_categories[c.Id]
if (c.ParentId != 0) // The is no NULL for int, you might want to use the nullable type "int?" or an additional bool isRoot
{
if (tree == null) tree = new List<Category>();
tree.Add(c);
all_relation[0] = c.Id;
}else
{
all_relation[c.ParentId] = c.Id;
}
}
if (all_relation[0] != 0)
{
tree = sfSideTree(all_relation[0], all_categories, all_relation);
}
return tree;//returns the tree, or NULL
}
List<Category> sfSideTree (int[] branch, Dictionary<int, Category> categories, int[] relation)
{
List<Category> tree = new List<Category>();
if (branch != null)
{
foreach (var b in branch)
{
if (relation[b] != null)
{
categories[b].categories = sdSideTree(relation[b], categories, relation)
} else
{
categories[b].categories = new List<Category>();
}
tree = aux;
}
}
return tree;
}