2014-01-26 27 views
1

我想從物化類別路徑的數組中創建一個類別對象的數組。來自物化路徑的對象

var data = [ 
    'Business/Finance', 
    'Business/Management', 
    'Business/Management/Leadership', 
    'Business/Team/Leadership' 
]; 

// Expected results: 
var result = [ 
    { name: 'Business', trail: null, path: 'Business' }, 
    { name: 'Finance', trail: 'Business', path: 'Business/Finance' }, 
    { name: 'Management', trail: 'Business', path: 'Business/Management' }, 
    { name: 'Leadership', trail: 'Business/Management', path: 'Business/Management/Leadership' }, 
    { name: 'Team', trail: 'Business', path: 'Business/Team/Leadership' }, 
    { name: 'Leadership', trail: 'Business/Team', path: 'Business/Team/Leadership' } 
]; 

正如你所看到的,Business只應出現一次,因爲所有的人都只有子類別。但是,Leadership應該出現兩次,因爲它們都處於不同的結構中。

當你檢查小提琴http://jsfiddle.net/9uC9Z/你可以看到Business存在4次。

我該如何解決問題?

如果生成的代碼非常複雜,我將非常感激代碼註釋。

編輯: 的物化data陣列中的路徑字符串反映書籍類別層次結構。一個例子是:

{ 
    title: 'Leadership 101', 
    author: 'John Smith', 
    category: 'Business/Management/Leadership' 
} 

這只是代表一本書。我現在要爲每個類別創建一個MongoDB文檔。上面的樣書會產生三個類別對象(商業,管理,領導力)。但是,如果某個類別(或子類別)對象/文檔已經存在,則不需要創建另一個。 result因此表示我將存儲在MongoDB集合中的類別對象。 (我將添加的類別之間的關係,但不是當前問題的一部分。)

+0

嗨,你問的是如何重組「數據」?它目前是一串字符串。你在問如何改變「數據」中的值的表示?或者需要有一個字符串數組作爲輸入數據?對不起,我不清楚。 – lorinpa

+0

@ user2658013感謝您的評論。我編輯了我的帖子。如果我仍然不清楚,請告訴我。 –

回答

0

功能的方法:

function extract (path, trail) { 
    if (path.length === 0) { 
     return []; 
    } 
    var item = { 
     name: path[path.length - 1], 
     trail: trail.length === 0 ? null : trail.join('/'), 
     path: path.join('/') 
    }; 
    var result = extract(path.slice(0, -1), path.slice(0, -2)).concat([item]); 
    return result; 
} 

function distinct (xs) { 
    function eq (a, b) { 
     return JSON.stringify(a) === JSON.stringify(b); 
    } 

    function contains (xs, x) { 
     for (var i = xs.length - 1; i >= 0; i--) { 
      if (eq(xs[i], x)) { 
       return true; 
      } 
     } 
     return false; 
    } 

    var result = []; 
    for (var i = xs.length - 1; i >= 0; i--) { 
     if (!contains(result, xs[i])) { 
      result.push(xs[i]); 
     } 
    } 
    return result; 
} 

var result = data. 
    map(function(x) { return x.split('/') }). 
    map(function(x) { return extract(x, x.slice(0, -1)) }). 
    reduce(function(a, b) { return a.concat(b)}); 

result = distinct(result); 

你可以從一些圖書館的一些更強大的替代distinct功能。在其他地方使用JSON.stringify(a) === JSON.stringify(b)時要小心對象相等。你可以在這裏閱讀更多關於它How to determine equality for two JavaScript objects?

+0

感謝您的回答。我可以使用http://lodash.com/或https://npmjs.org/上提供的任何其他庫。所以我可以用Lo-Dash中的'_.isEqual()'替換'distinct()'? –

+0

'distinct'在這裏可以正常工作,並且可以保持原樣。你可以用'將數組作爲參數並返回唯一值的東西'替換它 – pyanzin