ضغط هرمي الكائن في جافا سكريبت
-
12-09-2019 - |
سؤال
هل هناك نهج عام "ضغط" الكائنات المتداخلة إلى مستوى واحد:
var myObj = {
a: "hello",
b: {
c: "world"
}
}
compress(myObj) == {
a: "hello",
b_c: "world"
}
أعتقد أن هناك بعض العودية المعنية، لكنني أحسب أنني لست بحاجة إلى إعادة اختراع العجلة هنا ...!
المحلول
function flatten(obj, includePrototype, into, prefix) {
into = into || {};
prefix = prefix || "";
for (var k in obj) {
if (includePrototype || obj.hasOwnProperty(k)) {
var prop = obj[k];
if (prop && typeof prop === "object" &&
!(prop instanceof Date || prop instanceof RegExp)) {
flatten(prop, includePrototype, into, prefix + k + "_");
}
else {
into[prefix + k] = prop;
}
}
}
return into;
}
يمكنك تضمين الأعضاء الموروثين من خلال المرور true
في المعلمة الثانية.
بعض التحذيرات:
الكائنات العودية لن تعمل. علي سبيل المثال:
var o = { a: "foo" }; o.b = o; flatten(o);
سوف تابع حتى يلقي استثناء.
مثل إجابة Ruquay، تسحب هذا عناصر الصفيف تماما مثل خصائص الكائنات الطبيعية. إذا كنت ترغب في الحفاظ على صفائف سليمة، أضف "
|| prop instanceof Array
"للاستثناءات.إذا اتصلت بهذا على الكائنات من نافذة أو إطار مختلف، فلن يتم تضمين التواريخ والتعبيرات العادية، منذ
instanceof
لن تعمل بشكل صحيح. يمكنك إصلاح ذلك عن طريق استبداله بطريقة Tostring الافتراضية مثل هذا:Object.prototype.toString.call(prop) === "[object Date]" Object.prototype.toString.call(prop) === "[object RegExp]" Object.prototype.toString.call(prop) === "[object Array]"
نصائح أخرى
إليك واحدة سريعة، ولكن احترس، B / C سوف ليس العمل W / المصفوفات والقيم الخالية (B / C إرجاع نوع "كائن").
var flatten = function(obj, prefix) {
if(typeof prefix === "undefined") {
prefix = "";
}
var copy = {};
for (var p in obj) {
if(obj.hasOwnProperty(p)) {
if(typeof obj[p] === "object") {
var tmp = flatten(obj[p], p + "_");
for(var q in tmp) {
if(tmp.hasOwnProperty(q)) {
copy[prefix + q] = tmp[q];
}
}
}
else {
copy[prefix + p] = obj[p];
}
}
}
return copy;
}
var myObj = {
a: "level 1",
b: {
a: "level 2",
b: {
a: "level 3",
b: "level 3"
}
}
}
var flattened = flatten(myObj);
إليك سريعة coffeescript النسخة القائمة إيقاف إجابة ماثيو كروملي (لم أستخدم includePrototype
كما لم يكن لدي أي حاجة لذلك):
flatten = (obj, into = {}, prefix = '', sep = '_') ->
for own key, prop of obj
if typeof prop is 'object' and prop not instanceof Date and prop not instanceof RegExp
flatten prop, into, prefix + key + sep, sep
else
into[prefix + key] = prop
into
وإصدار Unflatten الأساسي، والتي من شأنها أن تفشل بلا شك مع فواصل متكررة وغيرها من هذه الخدامة:
unflatten = (obj, into = {}, sep = '_') ->
for own key, prop of obj
subKeys = key.split sep
sub = into
sub = (sub[subKey] or= {}) for subKey in subKeys[...-1]
sub[subKeys.pop()] = prop
into
fwiw، يمكنني استخدام هذه الوظائف لدفع الرسوم البيانية كائن أحمر الخلاص, ، والتي تدعم فقط عمق واحد من أزواج المفتاح / القيمة.