2017-04-23 1 views
0

Wenn ich ein Array mit einem Bündel von Stellen haben sortiert alle alten wie:Javascript - Wie vergleicht und sortiert man ein Array basierend auf der Reihenfolge des zweiten Arrays?

[ 
    { 
     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" 
    } 
] 

jedoch eine andere Anordnung, die die Struktur des ersten Feldes entscheidet auf der Grundlage der ids des ersten Arrays:

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

Was wäre der effizienteste Weg diese zu sortieren, so dass das erste Array nach dem zweiten Array sortiert ist?

Ich würde erwarten, dass die resultierende Anordnung so etwas wie folgt aussehen:

[ 
    { 
     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

Wie berechne ich 'Einzug'-Wert? Was ist Logik dahinter? –

+0

Sie möchten also ein abgeflachtes Array mit einem Einzugfeld, das angibt, wie tief das Kind in der Struktur ist, statt einer verschachtelten Struktur wie Arrays. Wäre nicht ID: 5 in diesem Fall ein Einzug von 2 anstelle von 1? – Sasang

+0

Eine flache Anordnung wäre vorzuziehen. Der Einzug gibt an, wie viele Eltern es hat (oder wie tief im Baum es geschachtelt ist). – Winter

Antwort

1

Sie können Ihre Daten Array von Index bestellen und es dann durch die Reihenfolge Array bestellen;

den Einzug erhalten Sie die Eltern Einbuchtung verfolgen müssen vor und fügen Sie ein:

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

Sie müssen zunächst einen Baum mit den Abhängigkeiten erzeugen und dann den Einzug machen für alle Elemente des Originalarrays.

Dieser Vorschlag funktioniert auch für unsortierte Daten/Relationen.

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

für die Bestellung, wandeln das erste Array in eine Map, dann von diesem in die erste Anordnung, die Informationen ziehen.

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})); 
} 

Dies wird Ihnen name, id und parent in der Reihenfolge geben Sie wollen. Die Berechnung von indent bleibt dem Leser überlassen (oder sollte eine andere Frage sein).

Verwandte Themen