2016-08-09 180 views
0

Ich habe ein Objekt, das ich in zwei Arrays auseinander nehmen musste, um richtig zu handhaben. Es sah wie folgt aus:reduzieren Schlüsselwertpaare in JS-Array zu Objekt

{ 
    city:"stuttgart", 
    street:"randomstreet", 
    ... 
} 

Da es eine bestimmte Richtlinie passen muss ich es konvertieren musste:

[ 
    {key:"city", value:"stuttgart"} 
    {key:"street", value:"randomstreet"}, 
    ... 
] 

dafür habe ich erste

var mapFromObjectWithIndex = function (array) { 
    return $.map(array, function(value, index) { 
    return [value]; 
    }); 
}; 

var mapFromObjectWithValue = function (array) { 
    return $.map(array, function(value, index) { 
    return [index]; 
    }); 
}); 

zwei erstellen Arrays, eine enthält den alten Schlüssel, die andere hält den alten Wert. Dann habe ich eine andere, eine zweidimensionale Anordnung zu einem einzigen Array abzubilden, dies zu tun

var mapToArray = function (arrayValue, arrayIndex) { 
    var tableData = []; 
    for (var i = 0; i<arrayIndex.length; i++){ 
    tableData[i] = {key:arrayIndex[i] , value:arrayValue[i]}; 
    } 
    return tableData; 
}; 

(vielleicht habe ich schon von hier vermasselt, kann dies nicht leichter gemacht werden?)

Nun verwende ich die Array (tableData), um die Daten in einem Formular anzuzeigen. Die Wertfelder können bearbeitet werden. Am Ende möchte ich das Array (tableData) zu seinem Original konvertieren. (siehe erstes Objekt)

Bitte beachten Sie, dass das Originalobjekt nicht nur Strings als Werte enthält, sondern auch Objekte enthalten kann.

+0

nur eine Randnotiz: Kyes in Objekte sind nicht die ursprüngliche Ordnung aufrechtzuerhalten garantiert. Nachdem Sie also Ihr Objekt in ein Array konvertiert haben, können Ihre Daten in zufälliger Reihenfolge vorliegen. – strah

Antwort

3

denke ich Umwandlung auf jeden Fall einfacher sein kann:

var obj = { 
 
    city:"stuttgart", 
 
    street:"randomstreet", 
 
}; 
 

 
var tableData = Object.keys(obj).map(k => {return {key: k, value: obj[k]}}); 
 

 
console.log(tableData); 
 

 
var dataBack = {}; 
 
tableData.forEach(o => dataBack[o.key] = o.value); 
 

 
console.log(dataBack);

Was tun Sie mit Objekten zu tun? Willst du sie auch erweitern? Wenn ja Sie so etwas tun können (und es funktioniert mit verschachtelten Objekten als auch):

var obj = { 
 
    city:"stuttgart", 
 
    street:"randomstreet", 
 
    obj: {a: 'a', b: 'b'}, 
 
    subObject: {aha: {z: 'z', y: 'y'}} 
 
}; 
 

 
function trasformToTableData(obj) { 
 
    if (typeof obj !== 'object') return obj; 
 
    return Object.keys(obj).map(k => {return {key: k, value: trasformToTableData(obj[k])}}); 
 
} 
 

 
var tableData = trasformToTableData(obj); 
 
console.log(tableData); 
 

 
function transformBack(obj) { 
 
    if (Array.isArray(obj)) { 
 
    var support ={}; 
 
    for (let i = 0; i < obj.length; i++) { 
 
     support[obj[i].key] = transformBack(obj[i].value) 
 
    } 
 
    return support; 
 
    } 
 
    return obj; 
 
} 
 

 
var dataBack = {}; 
 
tableData.forEach(o => dataBack[o.key] = transformBack(o.value)); 
 

 
console.log(dataBack);

+0

Ich denke, Ihre Antwort passt mir am besten und ist am vollständigsten und flexibelsten. Danke auch für die Vereinfachung des gesamten Prozesses. Auch das erste Mal, dass ich Pfeilnotation sehe (was zumindest Webstorm nicht mochte, also schrieb ich um) – undefinedMayNotBeNull

+0

@MichaelGerullis froh, dass es geholfen hat! Arrows-Funktionen sind ein ziemlich mächtiges Werkzeug von ES6 - nicht in diesem Beispiel, aber sie stellen automatisch die Bindung dieses '' '- Schlüsselwortes ein.Natürlich können sie in normalen Inline-Funktionen geändert werden – rpadovani

2

Diese Funktion wird Ihr Objekt in einem Array Karte, wenn Sie objVar.mapToArray() nennen, durch Object.keys() mit und .map()

Object.prototype.mapToArray = function() { 
    return Object.keys(this).map(function(v) { 
    return { key: v, value: this[v] }; 
    }.bind(this)); 
} 
+0

1.: map() hat ein zweites Argument, Sie müssen nicht binden, 2.: Wenn Sie einen dicken Pfeil verwenden, brauchen Sie nicht einmal dieses zweite Argument, und 3.: Jungs, hör auf, einige native Prototypen für jedes kleine, kleine Dienstprogramm, das du schreibst, zu erweitern. Vor allem nicht den Prototyp von Object erweitern, warum? weil '" wtf ".mapToArray() oder window.addEventListener.mapToArray()' * everything * erbt es. halte es einfach: 'var mapToArray = obj => Objekt.schlüssel (obj) .map (k => ({schlüssel: k, wert: obj [k]}) ' – Thomas

2

Lassen Sie uns etwas Spaß haben und wenden uns Objekt in iterable die Arbeit zu tun wie folgt;

var input = {city:"stuttgart", street:"randomstreet", number: "42"}; 
 
    output = []; 
 
input[Symbol.iterator] = function*(){ 
 
          var ok = Object.keys(this), 
 
           i = 0; 
 
          while (i < ok.length) yield {key : ok[i], value: this[ok[i++]]}; 
 
         }; 
 
output = [...input]; 
 
console.log(output);

+0

Kannst du erklären, wie deine Antwort funktioniert? Außerdem scheint die Ausgabe nicht in der richtigen Form zu sein. – Cristy

+1

@Cristy Danke ich habe die Ausgabe korrigiert, um wie erforderlich anzuzeigen. In diesem Snippet mache ich ein Objekt iterierbar, indem ich ihm eine Symbol.iterator-Methode zuweise. Dies macht Iteratoren wie die 'for of'-Schleife oder den Spread-Operator in der Lage, dieses Objekt zu iterieren (durch Aufrufen der Iterator-Methode erhalten sie ein Iterator-Objekt zurück und rufen es als nächste Methode auf - AKA-Generatoren-Iteratoren) Ausbeute in der Symbol.iterator-Funktion (Generator-Funktion) So ist es also. :) – Redu

1

Ich würde so etwas tun:

var dataObj = { 
 
    city:"stuttgart", 
 
    street:"randomstreet", 
 
}; 
 

 
function toKeyValue(obj) { 
 
    var arr = []; 
 
    for (var key in obj) { 
 
    if(obj.hasOwnProperty(key)) { 
 
     arr.push({'key': key, 'value': obj[key]}); 
 
    } 
 
    } 
 
    return arr; 
 
} 
 

 
var arrayKeyValue = toKeyValue(dataObj); 
 
console.log(arrayKeyValue);