Question

Y at-il une approche générique de « compression » des objets imbriqués à un seul niveau:

var myObj = {
    a: "hello",
    b: {
        c: "world"
    }
}

compress(myObj) == {
    a: "hello",
    b_c: "world"
}

Je suppose qu'il y aurait un peu impliqué récursion, mais je pensais que je ne ai pas besoin de réinventer la roue ici ...!?

Était-ce utile?

La solution

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

Vous pouvez inclure des membres hérités des membres en passant true dans le second paramètre.

Quelques mises en garde:

  • Les objets récursifs ne fonctionneront pas. Par exemple:

    var o = { a: "foo" };
    o.b = o;
    flatten(o);
    

    sera récursif jusqu'à ce qu'il lève une exception.

  • Comme la réponse de ruquay, ce tire les éléments du tableau, tout comme les propriétés des objets normaux. Si vous voulez garder les tableaux intacts, ajoutez "|| prop instanceof Array" des exceptions.

  • Si vous appelez cela sur des objets à partir d'une autre fenêtre ou un cadre, les dates et les expressions régulières ne seront pas inclus, puisque instanceof ne fonctionnera pas correctement. Vous pouvez résoudre ce problème en remplaçant par la méthode toString par défaut comme ceci:

    Object.prototype.toString.call(prop) === "[object Date]"
    Object.prototype.toString.call(prop) === "[object RegExp]"
    Object.prototype.toString.call(prop) === "[object Array]"
    

Autres conseils

Voici un rapide, mais attention, b / c il sera pas travail w / tableaux et des valeurs nulles (b / c leurs déclarations typeof "objet").

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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top