2017-04-23 65 views
0

如果我有一幫樁的陣列來分類任何舊的如何:JavaScript的 - 如何比較和排序基於第二個數組的順序的一個數組?

[ 
    { 
     id: 1, 
     name: "first parent post" 
    }, 
    { 
     id: 2, 
     name: "second child of first parent post" 
    }, 
    { 
     id: 3, 
     name: "second parent post" 
    }, 
    { 
     id: 4, 
     name: "first child of first parent post" 
    }, 
    { 
     id: 5, 
     name: "first child of second parent post" 
    } 
] 

然而,另一個數組決定是第一組的基礎上,第一陣列的IDS結構:

[ 
    { 
     id: 1, 
     parent: 0 
    }, 
    { 
     id: 4, 
     parent: 1 
    }, 
    { 
     id: 2, 
     parent: 1 
    }, 
    { 
     id: 3, 
     parent: 0 
    }, 
    { 
     id: 5, 
     parent: 3 
    } 
] 

將這些排序的最有效方法是什麼,以便第一個數組按第二個數組排序?

我希望得到的陣列看起來像這樣:

[ 
    { 
     id: 1, 
     name: "first parent post", 
     indent: 0 
    }, 
    { 
     id: 4, 
     name: "first child of first parent post", 
     indent: 1 
    }, 
    { 
     id: 2, 
     name: "second child of first parent post", 
     indent: 1 
    }, 
    { 
     id: 3, 
     name: "second parent post", 
     indent: 0 
    }, 
    { 
     id: 5, 
     name: "first child of second parent post", 
     indent: 1 
    } 
] 
+0

如何計算'indent'值?這背後的邏輯是什麼? –

+0

所以你需要一個帶有縮進字段的扁平數組,該字段指定了子樹在樹中的深度,而不是像數組這樣的嵌套樹。在這種情況下,不會有ID:5的縮進2,而不是1? – Sasang

+0

平面陣列將是更可取的。縮進表示它有多少個父母(或者它嵌套的樹有多深)。 – Winter

回答

1

你可以爲了通過索引數據數組,然後由順序排列責令;

得到壓痕你必須上游軌道父母的壓痕,並添加一個:

var data = [ 
 
    { 
 
     id: 1, 
 
     name: "first parent post" 
 
    }, 
 
    { 
 
     id: 2, 
 
     name: "second child of first parent post" 
 
    }, 
 
    { 
 
     id: 3, 
 
     name: "second parent post" 
 
    }, 
 
    { 
 
     id: 4, 
 
     name: "first child of first parent post" 
 
    }, 
 
    { 
 
     id: 5, 
 
     name: "first child of second parent post" 
 
    } 
 
] 
 

 
var ord = [ 
 
    { 
 
     id: 1, 
 
     parent: 0 
 
    }, 
 
    { 
 
     id: 4, 
 
     parent: 1 
 
    }, 
 
    { 
 
     id: 2, 
 
     parent: 1 
 
    }, 
 
    { 
 
     id: 3, 
 
     parent: 0 
 
    }, 
 
    { 
 
     id: 5, 
 
     parent: 3 
 
    } 
 
    
 
] 
 
// first you arrange the data element by index 
 
dataByIndex = data.reduce((ac, x) => { 
 
    ac[x.id] = x; 
 
    return ac 
 
},[]) 
 

 
// then you order them by the ord array 
 
var res = ord.reduce((ac, x, i) => { 
 
    var item = dataByIndex[x.id] 
 
    item.indent = x.parent === 0 ? 0 : getParentIndentPlusOne(ac, x.parent) 
 
    
 
    return [...ac, item] 
 
    }, []) 
 
    
 
function getParentIndentPlusOne(ac, id){ 
 
    var i = ac.length 
 
    while (--i > -1){ 
 
    if (id === ac[i].id) return ac[i].indent + 1 
 
    } 
 
} 
 
    
 

 
    
 
console.log(res)

1

您需要首先生成具有依賴性的樹,然後渲染縮進爲原始數組的所有項目。

該建議也適用於未排序的數據/關係。

function getDataWithIndent(data, relation) { 
 
    var hash = Object.create(null), 
 
     tree = function (data, root) { 
 
      var r = [], o = {}; 
 
      data.forEach(function (a) { 
 
       a.children = o[a.id] && o[a.id].children; 
 
       o[a.id] = a; 
 
       if (a.parent === root) { 
 
        r.push(a); 
 
       } else { 
 
        o[a.parent] = o[a.parent] || {}; 
 
        o[a.parent].children = o[a.parent].children || []; 
 
        o[a.parent].children.push(a); 
 
       } 
 
      }); 
 
      return r; 
 
     }(relation, 0), 
 
     result = []; 
 

 
    data.forEach(function (a) { 
 
     hash[a.id] = a; 
 
    }); 
 
    tree.forEach(function iter(indent) { 
 
     return function (a) { 
 
      hash[a.id].indent = indent; 
 
      result.push(hash[a.id]); 
 
      Array.isArray(a.children) && a.children.forEach(iter(indent + 1)); 
 
     }; 
 
    }(0)); 
 
    return result; 
 
} 
 

 
var data = [{ id: 1, name: "first parent post" }, { id: 2, name: "second child of first parent post" }, { id: 3, name: "second parent post" }, { id: 4, name: "first child of first parent post" }, { id: 5, name: "first child of second parent post" }], 
 
    relation = [{ id: 1, parent: 0 }, { id: 4, parent: 1 }, { id: 2, parent: 1 }, { id: 3, parent: 0 }, { id: 5, parent: 3 }], 
 
    result = getDataWithIndent(data, relation); 
 
    
 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

-1

對於排序,第一陣列轉換成Map,然後拉從該信息到第一陣列。

function combineArrays(arr1, arr2) { 
    let names = new Map(arr1.map(({id, name}) => [id, name])); 
    return arr2.map(({id, parent}) => ({id: id, name: names.get(id), parent: parent})); 
} 

這會給你nameidparent你想要的順序。計算indent作爲練習留給讀者(或者應該是一個不同的問題)。

相關問題