2017-12-16 4 views
0

어떤 폴더가 다른 폴더에 있는지 볼 수있는 방식으로 저장된 폴더 개체가 있습니다. 이러한 개체는 id, nameparentId 특성을가집니다. 각 폴더의 parentId은 다른 폴더의 id입니다. 루트 폴더의 상위 ID가 null입니다.생성되는 새 폴더의 부모 ID 역할을 할 특정 폴더 경로 문자열에서 마지막 폴더 ID 가져 오기

새 폴더를 만들 수있는 양식이 있습니다. 양식은 name (문자열) 및 parent (문자열) 입력을받습니다. 이름은 무엇이든 될 수 있지만 부모는 기존 폴더 형식 (예 : "Documents|Books|Fiction")이어야합니다. 이미있는 폴더가없는 경우 초기 Documents 폴더를 만들려면 부모를 비워 둘 수 있습니다.

부모의 파일 경로가 지정된 올바른 폴더에 새 폴더가 매핑되도록 알고리즘을 찾는 데 어려움을 겪고 있습니다.

Documents|Holidays

Documents|Books|Holidays

Documents|Jobs|Books|Holidays

를 내가 컨트롤러에서 name"My Day in Paris"parent"Documents|Books|Holidays"에 새 폴더를 생성하고 있다고 할 수 있습니다 : 예를 들어, 폴더 구조는 다음과 같은 경우 방법을 CreateFolder에 대한 새 Folder 개체를 데이터베이스에 저장하기 전에이 Folder ob 제공해야합니다. 상위 폴더의 ParentId을 꺼냅니다. 우리의 경우 부모는 경로가 "Documents|Books|Holidays"Holidays 폴더입니다.

예를 들어, 데이터베이스 (의사 코드)를 쿼리 할 수 ​​있습니다. db.Folders.where(x => x.Name == "Holidays").Select(y => y.Id).single(); 그러나 올바른 ParentId를 설정하기 위해 파일 경로에서 올바른 폴더를 가져 오지 못합니다.

어떻게 이런 식으로 상위 ID를 얻을 수 있습니까? 나는 여러 해 동안 주위를 검색해 보았고 알고리즘은 있지만 운을 찾기 위해 노력했다.

직접적인 업데이트. 반환 할 올바른 값에 도달하지만이 값을 반환하는 대신 이전에 일시 중지 된 순환 순환으로 다시 돌아갑니다. 출력 값을 되돌리려면 어떻게 되나요?

public int GetIdFromPath(string path) 
     { 
      int _parentId = 0; 
      var folderStructure = GetFolderStructure(); 

      if (path != null) 
      { 
       _parentId = recursiveFunction(path, folderStructure); 
       return _parentId; 
      } 

      return _parentId; 
     } 

     private int recursiveFunction(string path, List<Folder> folders) 
     { 
      var splitPath = path.Split('|'); 
      var _parentId = 0; 
      foreach (var item in splitPath) 
      { 
       try 
       { 
        foreach (var folder in folders) 
        { 
         if (folder.Name == item) 
         { 
          splitPath = splitPath.Where(x => x != item).ToArray(); 
          _parentId = folder.Id; 

          if (splitPath.Count() > 0) 
          { 
           var newPath = string.Join("|", splitPath); 
           recursiveFunction(newPath, folder.FolderBookmarks.OfType<Folder>().ToList()); 
          } 

          return _parentId; 
         } 
        } 
       } 
       catch (Exception e) 
       { 
        return _parentId; 
       } 
      } 

      return _parentId; 
     } 

     public List<Folder> GetFolders() 
     { 
      var folders = db.Bookmarks.OfType<Folder>().ToList(); 
      return folders; 
     } 

     public List<Folder> GetFolderStructure() 
     { 
      var folders = GetFolders(); 

      foreach (var folder in folders) 
      { 
       var bookmarks = db.Bookmarks.Where(x => x.ParentId == folder.Id).ToList(); 
       folder.FolderBookmarks = bookmarks; 
      } 

      return folders; 
     } 
+0

'Parent' /'Children' 속성이있는 트리보기 구조와 비슷합니까? – Aybe

+0

안녕 Aybe, 알 겠어,하지만 난 parent_Id 참조를 사용하여 이것을 완료하려고합니다. 감사. – naz786

+0

재귀 알고리즘을 작성해야합니다.아마도 GetFiles() 메서드를 사용하고 모든 하위 폴더를 가져 오는 대신 한 번에 하나의 디렉터리를 가져 오는 것이 좋습니다. 코드는 매우 간단합니다. 전에 여러 번 써 보았습니다. – jdweng

답변

0

나는 해결책을 마련했다. 변수 folders은 폴더 개체의 목록입니다. (참고 : 폴더에는 폴더가 여러 개 있습니다.) 아래 코드는 상위 ID를 경로 이름과 일치하는 폴더 이름의 폴더 ID로 설정합니다. 그런 다음 폴더 목록은 해당 폴더의 내부 폴더 목록으로 설정됩니다. 이 폴더 내에서 볼 수 있습니다. (이 컨텍스트에서는 중복 폴더 이름을 허용하지 않습니다. 감사합니다 Reza, 귀하의 의견을 도왔습니다!

public int GetParentIdFromPath(string path) 
    { 
     int _parentId = 0; 

     if (path != null) 
     { 
      var folders = GetFolderStructure(); 
      var splitPath = path.Split('|'); 

      foreach (var item in splitPath) 
      { 
       _parentId = folders.Where(x => x.Name == item).SingleOrDefault().Id; 
       folders = folders.Where(x => x.Name == item).SingleOrDefault().FolderBookmarks.OfType<Folder>().ToList(); 
      } 

      return _parentId; 
     } 

     return _parentId; 
    } 
+0

누구나 내가 코딩 알고리즘에 대해 더 능숙하고 빠를 수있는 방법을 제안 할 수 있습니까? 이것은 생각하는 날과 여기에서받은 지침에서 발전하는 데 5 시간이 걸렸습니다. 내 친구들은 내가 생각했던 것보다 더 빨리이 문제를 해결했다. – naz786

1

당신은이 같은 단계로 각 상위 단계를 찾아도 처리해야합니다 예외 :

int? _parentId = null; 
foreach (var item in path.Split('|')) 
{ 
    var folder = db.Folders 
        .where(x => x.Name == item&&x.ParentId = _parentId) 
        .Select(y => y.Id) 
        .Single(); 
    _parentId = folder.Id; 
} 
return _parentId; 
+0

재귀 aproximation을 사용하여 aswer를 작성했지만이 방법이 마음에 들었습니다. – mnieto

+0

감사합니다. Reza, 이해합니다. 그러나 기존 폴더와 이름이 같은 폴더에는 적합하지 않습니다. 예를 들어, "Documents | University | Pictures"및 "Documents | University | Pictures"가 있고 새 폴더의 파일 경로가 "Documents | University | Pictures"인 경우 코드에 ''Picture "'폴더가 2 개 있기 때문에 id. 코드가 예외를 throw합니다. 이름을 가진 폴더의 목록을 만들어서 처리하려고 시도하지만 올바른''Pictures "'폴더의 ID를 얻는 방법을 모르겠습니다. – naz786

+1

@ naz786- 코드를 이해하지 못했습니다. 위에서 아래로 트리를 추적하므로 모든 검색은 상위의 하위에서 실행됩니다. 예를 들어 우리가 검색하는 '그림'을 검색 할 때 부모의 하위 ('대학 '자녀들). –

관련 문제