UIZE JavaScript Framework

MODULES Uize.Data.Flatten

1. Introduction

The Uize.Data.Flatten package provides methods for flattening a hierarchical / tree structured object to a flat, key/value hash table, as well as unflattening a key/value hash table to produce a hierarchical / tree structured object.

DEVELOPERS: Chris van Rensburg

1.1. In a Nutshell

The methods of the Uize.Data.Flatten module make it easy to represent a hierarchical, tree structure or graph object using a single level hash / dictionary / lookup object.

When flattening a hierarchical object to a hash structure using the Uize.Data.Flatten.flatten method, information about the original structure of object being flattened is retained in the key names of the flattened object by using the dereferencing path to the leaf nodes to form the key names. This has the advantage of providing a natural way to derive keys for the flattened object that don't collide for different leaf nodes, as well as retaining information necessary to reconstitute the original source object from a flattened object using the companion Uize.Data.Flatten.unflatten method.

EXAMPLE

Uize.Data.Flatten.flatten ({
  animals:{
    pets:{
      dogs:{
        smallBreeds:['West Highland White','Miniature Chihuahua','Teacup Poodle'],
        largeBreeds:['Afghan','Great Dane','Irish Wolfhound','St. Bernard']
      },
      cats:['Persian','Siamese','Hairless']
    },
    wildAnimals:{
      dogs:['Coyote','Dingo'],
      cats:['Bobcat','Cheetah','Leopard','Lion','Lynx','Mountain Lion','Tiger'],
      other:['Aardvark','Elephant','Hedgehog','Opossum','Wildebeest','Zebra']
    }
  }
});

In the above example, we are flattening a hierarchical object that contains a (somewhat unscientific) classification of animals. The Uize.Data.Flatten.flatten method creates the resulting hash / lookup object that contains only properties for the leaf node properties of the hierarchical object, and where the key names represent the dereferencing

RESULT

{
  'animals.pets.dogs.smallBreeds':['West Highland White','Miniature Chihuahua','Teacup Poodle'],
  'animals.pets.dogs.largeBreeds':['Afghan','Great Dane','Irish Wolfhound','St. Bernard'],
  'animals.pets.cats':['Persian','Siamese','Hairless'],
  'animals.wildAnimals.dogs':['Coyote','Dingo'],
  'animals.wildAnimals.cats':['Bobcat','Cheetah','Leopard','Lion','Lynx','Mountain Lion','Tiger'],
  'animals.wildAnimals.other':['Aardvark','Elephant','Hedgehog','Opossum','Wildebeest','Zebra']
}

1.1.1. A Real World Example

To illustrate how the Uize.Data.Flatten module might be used, let's consider a real world example.

In our example, we have a hierarchical object that contains all the resource strings that need to be translated for an entire Web application, where that object is structured according to the various sections of the application and the UI components used in each section. The object may look something like the following...

RESOURCE STRINGS OBJECT

var resourceStrings = {
  login:{
    username:'Username',
    password:'Password'
  },
  account:{
    password:{
      changePassword:'Change Your Password',
      forgotPassword:'Forgot Your Password?'
    },
    changeEmail:'Change Your Primary Email Address',
    changeUsername:'Change Your Username',
    notification:'Modify Your Notification Settings'
  },
  home:{
    newForYou:'New Articles for You',
    friendActivity:'News from Your Social Circle'
  },
  feeds:{
    worldNews:'World News',
    localNews:'News in Your Local Area',
    aroundTheWeb:'Recommended from Around the Web',
    editFeeds:'Edit Your Feeds and Settings'
  }
};

In reality, there would be many more resource strings than just these, and the structure of the object could be arbitarily deep, depending on the organization of the sections, subsections, UI components, etc.

Now, let's say that a translation agency that we wish to use to translate our English strings into German wishes to receive the list of strings in a simple, flat CSV file with only two columns for string key-value pairs - not an unrealistic scenario. If we wanted to take the above object and convert it to a flat CSV file of pure key-value pairs, we could do so using the Uize.Data.Flatten module with the following statement...

RESOURCE STRINGS OBJECT TO CSV

var csvText = Uize.Data.Csv.to (
  Uize.Data.NameValueRecords.fromHash (
    Uize.Data.Flatten.flatten (resourceStrings),
    0,
    1
  )
);

Admittedly, we're getting a little help here from two other modules: the Uize.Data.NameValueRecords module and the Uize.Data.Csv module.

In our statement, we are first flattening the resourceStrings object using the Uize.Data.Flatten.flatten method to produce a simple hash object, as follows...

FLATTENED HASH

{
  'login.username':'Username',
  'login.password':'Password',
  'account.password.changePassword':'Change Your Password',
  'account.password.forgotPassword':'Forgot Your Password?',
  'account.changeEmail':'Change Your Primary Email Address',
  'account.changeUsername':'Change Your Username',
  'account.notification':'Modify Your Notification Settings',
  'home.newForYou':'New Articles for You',
  'home.friendActivity':'News from Your Social Circle',
  'feeds.worldNews':'World News',
  'feeds.localNews':'News in Your Local Area',
  'feeds.aroundTheWeb':'Recommended from Around the Web',
  'feeds.editFeeds':'Edit Your Feeds and Settings'
}

Then, we take this hash object and use the Uize.Data.NameValueRecords.fromHash method to turn it into a name-value records array where name-value pairs are represented by two element arrays, as follows...

AS A NAME-VALUE RECORDS ARRAY

[
  ['login.username','Username'],
  ['login.password','Password'],
  ['account.password.changePassword','Change Your Password'],
  ['account.password.forgotPassword','Forgot Your Password?'],
  ['account.changeEmail','Change Your Primary Email Address'],
  ['account.changeUsername','Change Your Username'],
  ['account.notification','Modify Your Notification Settings'],
  ['home.newForYou','New Articles for You'],
  ['home.friendActivity','News from Your Social Circle'],
  ['feeds.worldNews','World News'],
  ['feeds.localNews','News in Your Local Area'],
  ['feeds.aroundTheWeb','Recommended from Around the Web'],
  ['feeds.editFeeds','Edit Your Feeds and Settings']
]

Now that we have essentially a table structure with rows and columns, we can easily serialize this as a CSV string using the Uize.Data.Csv.to method to produce a string that we can write to a .csv file that would look as follows...

CSV FILE

login.username,Username
login.password,Password
account.password.changePassword,Change Your Password
account.password.forgotPassword,Forgot Your Password?
account.changeEmail,Change Your Primary Email Address
account.changeUsername,Change Your Username
account.notification,Modify Your Notification Settings
home.newForYou,New Articles for You
home.friendActivity,News from Your Social Circle
feeds.worldNews,World News
feeds.localNews,News in Your Local Area
feeds.aroundTheWeb,Recommended from Around the Web
feeds.editFeeds,Edit Your Feeds and Settings

Once we have shipped our CSV formatted resource strings object off to the translators and they load the file into their translation management system to produce the translations and then provide us with the German translations in a new CSV file, we can import the translated strings from that CSV file using a reverse process as follows...

CSV BACK TO RESOURCE STRINGS

var resourceStrings = Uize.Data.Flatten.unflatten (
  Uize.Data.NameValueRecords.toHash (
    Uize.Data.Csv.from (csvText),
    0,
    1
  )
);

1.1.2. Unflattening a Flattened Object

The Uize.Data.Flatten module provides the Uize.Data.Flatten.unflatten method to allow the flattening performed by the Uize.Data.Flatten.flatten method to be reversed.

Using the Uize.Data.Flatten.unflatten method, a flattened object that was generated from a source object using the Uize.Data.Flatten.flatten method can be unflattened to produce an object with the contents of the original source object. Consider the following example...

EXAMPLE

Uize.Data.Flatten.unflatten ({
  'animals.pets.dogs.smallBreeds':['West Highland White','Miniature Chihuahua','Teacup Poodle'],
  'animals.pets.dogs.largeBreeds':['Afghan','Great Dane','Irish Wolfhound','St. Bernard'],
  'animals.pets.cats':['Persian','Siamese','Hairless'],
  'animals.wildAnimals.dogs':['Coyote','Dingo'],
  'animals.wildAnimals.cats':['Bobcat','Cheetah','Leopard','Lion','Lynx','Mountain Lion','Tiger'],
  'animals.wildAnimals.other':['Aardvark','Elephant','Hedgehog','Opossum','Wildebeest','Zebra']
});

In the above example, we are unflattening an object that contains a classification of animals, where the hierarchical classification information has been flattened into the key names using the Uize.Data.Flatten.flatten method with its default behavior of using the "." (period) character as a delimiter when generating key names from path segments. From the above statement, we get the following result...

RESULT

{
  animals:{
    pets:{
      dogs:{
        smallBreeds:['West Highland White','Miniature Chihuahua','Teacup Poodle'],
        largeBreeds:['Afghan','Great Dane','Irish Wolfhound','St. Bernard']
      },
      cats:['Persian','Siamese','Hairless']
    },
    wildAnimals:{
      dogs:['Coyote','Dingo'],
      cats:['Bobcat','Cheetah','Leopard','Lion','Lynx','Mountain Lion','Tiger'],
      other:['Aardvark','Elephant','Hedgehog','Opossum','Wildebeest','Zebra']
    }
  }
}

1.1.3. Advanced Features

The Uize.Data.Flatten module offers a few advanced features to address less common situations.

1.1.3.1. Using Custom Path Delimiter Strings

In cases where the default "." (period) character path delimiter is not suitable, the Uize.Data.Flatten module allows a custom path delimiter string to be specified when flattening and unflattening objects.

EXAMPLE

Uize.Data.Flatten.flatten (
  {
    foo:{
      bar:{
        baz:{
          qux:1,
          hello:'world'
        }
      }
    }
  },
  '/'
);

In the above example, we are flattening the source object using the "/" (forward slash) character as a path delimiter, which produces the following result...

RESULT

{
  'foo/bar/baz/qux':1,
  'foo/bar/baz/hello':'world'
}

Now, because the resulting flattened object was produced using a custom path delimiter string, that same path delimiter string needs to be specified when later unflattening the flattened object, as in...

EXAMPLE

Uize.Data.Flatten.unflatten (
  {
    'foo/bar/baz/qux':1,
    'foo/bar/baz/hello':'world'
  },
  '/'
);

RESULT

{
  foo:{
    bar:{
      baz:{
        qux:1,
        hello:'world'
      }
    }
  }
}

It's worth pointing out that if we didn't specify the custom path delimiter string that was originally used to flatten the object, the flattened object would not get unflattened correctly and would, in our example, just return an identical copy of the flattened object. The Uize.Data.Flatten.unflatten method would try to use the default "." (period) path delimiter string and wouldn't see any periods in the key names and so wouldn't reconstruct the hierarchical structure of the original object.

1.1.3.2. Using Custom Key Serialization and Parsing Functions

In cases where a simple string path delimiter is not adequate, the Uize.Data.Flatten module allows a custom path-to-key transformer function to be specified when flattening and unflattening objects.

EXAMPLE

Uize.Data.Flatten.flatten (
  {
    'foo.foo':{
      'bar:bar':{
        'baz|baz':{
          '"qux"':1,
          '\'hello\'':'world'
        }
      }
    }
  },
  function (_path) {return Uize.Json.to (_path,'mini')}
);

In the above example, the hierarchical object that we need to flatten contains all sorts of crazy characters in the names of properties. We can't use the default "." (period) character because there is property named "foo.foo". We can't specify a custom delimiter string of ":" or "|", nor of single or double quotes, because there are properties that contain those characters in their names. To resolve this dilemma, we instead specify a custom path-to-key transformer function that is using the Uize.Json.to method to serialize the path array to a JSON object, which produces the following output...

RESULT

{
  '[\'foo.foo\',\'bar:bar\',\'baz|baz\',\'"qux"\']':1,
  '[\'foo.foo\',\'bar:bar\',\'baz|baz\',\'\\\'hello\\\'\']':'world'
}

Using a custom path-to-key transformer function is a useful approach when you have no way of knowing or controlling the types of characters that may be contained in the names of properties in the hierarchical object you are trying to flatten.

If there's no way of knowing what character (or series of characters) you can count upon as a reliable delimiter string, then the only truly robust way to serialize the property paths in the hierarchical object to keys in the flattened object is to serialize the paths to JSON format (or some other serialization that can support any arbitrary characters). Although the key names produced for the flattened object with such an approach are clumsier and less elegant, this is a robust approach to generating unique keys for the flattened object.

1.1.3.2.1. To Unflatten, Specify a Parser / De-serializer

Whereas, when using custom path delimiter strings to flatten and unflatten objects one only needs to make sure to use the same delimiter string in both directions, using the function approach requires one to specify a path-to-key serializer when flattening and a key-to-path parser / de-serializer when unflattening.

So, for example, if we used a JSON serializer as the path-to-key transformer function when flattening a hierarchical object using the Uize.Data.Flatten.flatten method, then we would need to use a JSON parser as the key-to-path transformer function when unflattening the flattened object using the Uize.Data.Flatten.unflatten method.

Consider the following example...

EXAMPLE

Uize.Data.Flatten.unflatten (
  {
    '[\'foo.foo\',\'bar:bar\',\'baz|baz\',\'"qux"\']':1,
    '[\'foo.foo\',\'bar:bar\',\'baz|baz\',\'\\\'hello\\\'\']':'world'
  },
  function (_path) {return Uize.Json.from (_path)}
);

RESULT

{
  'foo.foo':{
    'bar:bar':{
      'baz|baz':{
        '"qux"':1,
        '\'hello\'':'world'
      }
    }
  }
},

1.1.3.3. Leaf Nodes

By default, the Uize.Data.Flatten.flatten method includes only the leaf nodes of the hierarchical source object when producing the flattened version of that object.

This is because the leaf nodes are all that are needed in order to re-constitute the original hierarchical source object from a flattened version of it, so including non-leaf nodes is redundant in this regard.

1.1.3.3.1. The Definition of Leaf Nodes

Technically, leaf nodes are defined as properties whose values are of any type other than plain object.

This means that properties with the following types of values would be considered leaf nodes...

arrays
functions
regular expressions
instances (of any object type other than JavaScript's built-in Object object)
strings
numbers (including special number type values like NaN, Infinity, and -Infinity)
booleans
undefined
null

Particularly as it relates to object type values (such as regular expressions, function references, instances of Uize.Class subclasses, etc.), this means that these values will not be traversed deeper - even if they contain custom properties. Any object value that is not a plain object (i.e. an instance of Object) will be treated as a leaf node value and not as a structure defining node.

1.1.3.3.2. Including Non-leaf Nodes

Non-leaf nodes of the source object can be included in the flattened object produced by the Uize.Data.Flatten.flatten method, by specifying the value true for the method's optional includeNonLeafNodesBOOL third argument.

Consider the following example...

EXAMPLE

Uize.Data.Flatten.flatten ({foo:{bar:{baz:{qux:1}}}},'.',true);

In the above example, if we didn't specify the value true for the includeNonLeafNodesBOOL argument, we would get the result {'foo.bar.baz.qux':1} since there is only this one leaf node in the source object. However, when we specify true for includeNonLeafNodesBOOL, then we get the following result...

RESULT

{
  'foo':{bar:{baz:{qux:1}}},
  'foo.bar':{baz:{qux:1}},
  'foo.bar.baz':{qux:1},
  'foo.bar.baz.qux':1
}

It should be pointed out that the various object values in the above object would contain shared references. So, for example, the value of the expression result ['foo.bar.baz'] would be a reference to the same object as the expression result ['foo.bar'].baz or the expression result.foo.bar.baz - the {qux:1} object.

Now, if you use the Uize.keys method on the above result, you get an array with dereferencing paths for all possible nodes in the hierarchical source object, as seen in the following example...

EXAMPLE

Uize.keys (
  Uize.Data.Flatten.flatten ({foo:{bar:{baz:{qux:1}}}},'.',true)
);

RESULT

[
  'foo',
  'foo.bar',
  'foo.bar.baz',
  'foo.bar.baz.qux'
]

1.2. Examples

There are no dedicated showcase example pages for the Uize.Data.Flatten module.

SEARCH FOR EXAMPLES

Use the link below to search for example pages on the UIZE Web site that reference the Uize.Data.Flatten module...

SEARCH

1.3. Implementation Info

The Uize.Data.Flatten module defines the Uize.Data.Flatten package under the Uize.Data namespace.

1.3.1. Features Introduced in This Module

The features listed in this section have been introduced in this module.

STATIC METHODS

Uize.Data.Flatten.flatten | Uize.Data.Flatten.unflatten

STATIC PROPERTIES

Uize.Data.Flatten.moduleName | Uize.Data.Flatten.pathToResources

1.3.2. Features Overridden in This Module

No features have been overridden in this module.

1.3.3. Features Inherited From Other Modules

This module has no inherited features.

1.3.4. Modules Directly Under This Namespace

There are no modules directly under this namespace.

1.3.5. Unit Tests

The Uize.Data.Flatten module is unit tested by the Uize.Test.Uize.Data.Flatten test module.

2. Static Methods

2.1. Uize.Data.Flatten.flatten

Flattens the specified source object to produce a one-level-deep hash / lookup / dictionary object, where the key names of this hash object are generated from the path information of the corresponding properties in the source object.

DIFFERENT USAGES

Flatten a Source Object, Using the Default Path-to-key Transformer

flattenedOBJ = Uize.Data.Flatten.flatten (sourceOBJ);

Flatten a Source Object, Specifying a Path Delimiter String

flattenedOBJ = Uize.Data.Flatten.flatten (sourceOBJ,pathDelimiterSTR);

Flatten a Source Object, Specifying a Path-to-key Transformer Function

flattenedOBJ = Uize.Data.Flatten.flatten (sourceOBJ,pathToKeyTransformerFUNC);

Flatten a Source Object, Including Non-leaf Nodes in the Flattened Object

flattenedOBJ = Uize.Data.Flatten.flatten (
  sourceOBJ,pathToKeyTransformerANYTYPE,includeNonLeafNodesBOOL
);

2.1.1. Flatten a Source Object, Using the Default Path-to-key Transformer

In the most basic usage, a hierarchical object can be flattened using the default "." (period) character as a path delimiter when generating key names for the flattened object.

SYNTAX

flattenedOBJ = Uize.Data.Flatten.flatten (sourceOBJ);

EXAMPLE

Uize.Data.Flatten.flatten ({
  foo:{
    bar:{
      baz:{
        qux:1,
        hello:'world'
      }
    }
  }
});

RESULT

{
  'foo.bar.baz.qux':1,
  'foo.bar.baz.hello':'world'
}

NOTES

see how to unflatten a source object, using the default key-to-path transformer

2.1.2. Flatten a Source Object, Specifying a Path Delimiter String

In cases where the default "." (period) character path delimiter is not suitable, a custom path delimiter string can be specified using the optional pathDelimiterSTR second argument.

SYNTAX

flattenedOBJ = Uize.Data.Flatten.flatten (sourceOBJ,pathDelimiterSTR);

EXAMPLE

Uize.Data.Flatten.flatten (
  {
    foo:{
      bar:{
        baz:{
          qux:1,
          hello:'world'
        }
      }
    }
  },
  '/'
);

RESULT

{
  'foo/bar/baz/qux':1,
  'foo/bar/baz/hello':'world'
}

NOTES

see how to unflatten a source object, specifying a path delimiter string

2.1.3. Flatten a Source Object, Specifying a Path-to-key Transformer Function

In cases where a simple string path delimiter is not adequate, a custom path-to-key transformer function can be specified using the optional pathDelimiterSTR second argument in place of the pathDelimiterSTR argument.

SYNTAX

flattenedOBJ = Uize.Data.Flatten.flatten (sourceOBJ,pathToKeyTransformerFUNC);

EXAMPLE

Uize.Data.Flatten.flatten (
  {
    'foo.bar':{
      'baz.qux':1
    }
  },
  function (_path) {return Uize.Json.to (_path,'mini')}
);

In the above example, we are specifying a custom path-to-key transformer function that is using the Uize.Json.to method to serialize the path array to a JSON object, which produces the following output...

RESULT

{
  '[\'foo.bar\',\'baz.qux\']':1
}

This is a useful approach for dealing with the possibility that property names in the unflattened source object may contain the very string delimiter that you decide to specify for the pathDelimiterSTR parameter. In this case, the property names contain periods, which conflicts with the default delimiter used by the Uize.Data.Flatten.flatten method. If we just went ahead and used the default behavior in this case, we would generate a flattened object that couldn't be converted back to the original object using the Uize.Data.Flatten.unflatten method, since we would have lost important path information.

Although the key names produced for the flattened object, when using a JSON serialization of the path array, are clumsier and less elegant, this is a robust approach to generating unique keys that can support any arbitrary characters in the names of properties in the source object.

NOTES

see how to unflatten a source object, specifying a key-to-path transformer function

2.1.4. Flatten a Source Object, Including Non-leaf Nodes in the Flattened Object

In special cases, non-leaf nodes of the source object can be included in the flattened object by specifying the value true for the optional includeNonLeafNodesBOOL third argument.

SYNTAX

flattenedOBJ = Uize.Data.Flatten.flatten (
  sourceOBJ,pathToKeyTransformerANYTYPE,includeNonLeafNodesBOOL
);

By default, the Uize.Data.Flatten.flatten method only includes leaf nodes in the flattened object that it produces, since the leaf nodes are all that are needed in order to reconstitute the original source object. Leaf nodes are the deepest properties in the source object (see The Definition of Leaf Nodes for a more technical definition).

There are some special circumstances in which it is useful to include non-leaf nodes. Consider the following example...

EXAMPLE

Uize.keys (
  Uize.Data.Flatten.flatten (
    {
      animals:{
        pets:{
          dogs:{
            smallBreeds:['West Highland White','Miniature Chihuahua','Teacup Poodle'],
            largeBreeds:['Afghan','Great Dane','Irish Wolfhound','St. Bernard']
          },
          cats:['Persian','Siamese','Hairless']
        },
        wildAnimals:{
          dogs:['Coyote','Dingo'],
          cats:['Bobcat','Cheetah','Leopard','Lion','Lynx','Mountain Lion','Tiger'],
          other:['Aardvark','Elephant','Hedgehog','Opossum','Wildebeest','Zebra']
        }
      }
    },
    '.',
    true
  )
);

In the above example, we are creating an array that contains all the dereferencing paths for all nodes from a hierarchical object that contains a classification of animals.

By specifying the value true for the optional includeNonLeafNodesBOOL parameter, the Uize.Data.Flatten.flatten method returns an object with additional keys for the animals, animals.pets, animals.pets.dogs, and animals.wildAnimals non-leaf nodes of the source object. We then use the Uize.keys method to obtain an array of just the keys from the flattened object, and this gives us the full set of dereferencing paths for all nodes of the original source object, producing the following array result...

RESULT

[
  'animals',
  'animals.pets',
  'animals.pets.dogs',
  'animals.pets.dogs.smallBreeds',
  'animals.pets.dogs.largeBreeds',
  'animals.pets.cats',
  'animals.wildAnimals',
  'animals.wildAnimals.dogs',
  'animals.wildAnimals.cats',
  'animals.wildAnimals.other'
}

NOTES

compare to the companion Uize.Data.Flatten.unflatten static method

IMPLEMENTATION INFO

this feature was introduced in this module

2.2. Uize.Data.Flatten.unflatten

DIFFERENT USAGES

Unflatten a Source Object, Using the Default Key-to-path Transformer

hierarchicalOBJ = Uize.Data.Flatten.unflatten (sourceOBJ);

Unflatten a Source Object, Specifying a Path Delimiter String

hierarchicalOBJ = Uize.Data.Flatten.unflatten (sourceOBJ,pathDelimiterSTR);

Unflatten a Source Object, Specifying a Key-to-path Transformer Function

hierarchicalOBJ = Uize.Data.Flatten.unflatten (sourceOBJ,keyToPathTransformerFUNC);

2.2.1. Unflatten a Source Object, Using the Default Key-to-path Transformer

In the most basic usage, an object that was flattened, using the "." (period) character as a path delimiter when generating key names for the flattened object, can unflattened by specifying just the flattened object using the sourceOBJ argument.

SYNTAX

hierarchicalOBJ = Uize.Data.Flatten.unflatten (sourceOBJ);

EXAMPLE

Uize.Data.Flatten.unflatten ({
  'foo.bar.baz.qux':1,
  'foo.bar.baz.hello':'world'
});

RESULT

{
  foo:{
    bar:{
      baz:{
        qux:1,
        hello:'world'
      }
    }
  }
}

NOTES

see how to flatten a source object, using the default path-to-key transformer

2.2.2. Unflatten a Source Object, Specifying a Path Delimiter String

In cases where a flattened object was created using a path delimiter string other than the default "." (period) character, such a flattened object can be unflattened by specifying the custom path delimiter string using the optional pathDelimiterSTR second argument.

SYNTAX

hierarchicalOBJ = Uize.Data.Flatten.unflatten (sourceOBJ,pathDelimiterSTR);

EXAMPLE

Uize.Data.Flatten.unflatten (
  {
    'foo/bar/baz/qux':1,
    'foo/bar/baz/hello':'world'
  }
  '/'
);

RESULT

{
  foo:{
    bar:{
      baz:{
        qux:1,
        hello:'world'
      }
    }
  }
}

NOTES

see how to flatten a source object, specifying a path delimiter string

2.2.3. Unflatten a Source Object, Specifying a Key-to-path Transformer Function

In cases where a flattened object was created using a path-to-key transformer function, such a flattened object can be unflattened by specifying a key-to-path transformer function, using the optional keyToPathTransformerFUNC second argument, that has the reverse effect of the path-to-key transformer function used when creating the flattened object.

SYNTAX

hierarchicalOBJ = Uize.Data.Flatten.unflatten (sourceOBJ,keyToPathTransformerFUNC);

EXAMPLE

Uize.Data.Flatten.unflatten (
  {
    '[\'foo.bar\',\'baz.qux\']':1
  },
  function (_key) {return Uize.Json.from (_key)}
);

In the above example, we are unflattening an object that was flattened by specifying a custom path-to-key transformer function that JSON serialized the property paths of the source object in order to generate the keys of the flattened object. Because of this, in order to unflatten this object we need to specify a key-to-path transformer function that has the reverse effect. The function that we have specified performs a JSON parse of a key using the Uize.Json.from method in order to produce a path array.

The above code produces the following output...

RESULT

{
  'foo.bar':{
    'baz.qux':1
  }
}

NOTES

see how to flatten a source object, specifying a path-to-key transformer function

NOTES

compare to the companion Uize.Data.Flatten.flatten static method

IMPLEMENTATION INFO

this feature was introduced in this module

3. Static Properties

3.1. Uize.Data.Flatten.moduleName

IMPLEMENTATION INFO

this feature was introduced in this module

3.2. Uize.Data.Flatten.pathToResources

IMPLEMENTATION INFO

this feature was introduced in this module