Recent Posts

Showing posts with label object. Show all posts
Showing posts with label object. Show all posts

How to: Serialize Object to JSON

JSON-js - JSON in JavaScript.

To convert an object to a string, use JSON.stringify:

var json_text = JSON.stringify(your_object, null, 2);
To convert a string to JSON object, use JSON.parse:

var your_object = JSON.parse(json_text);
It was recently recommended by John Resig:

...PLEASE start migrating your JSON-using applications over to Crockford's json2.js. It is fully compatible with the ECMAScript 5 specification and gracefully degrades if a native (faster!) implementation exists.

In fact, I just landed a change in jQuery yesterday that utilizes the JSON.parse method if it exists, now that it has been completely specified.

I tend to trust what he says on JavaScript matters :)

Newer browsers support the JSON object natively. The current version of Crockford's JSON library will only define JSON.stringify and JSON.parse if they're not already defined, leaving any browser native implementation intact.

How to: Convert HTML form data to JavaScript Object using jQuery

serializeArray  already does exactly that, you just need to massage the data into your required format:

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};
Example of this in action:

HTML:

<h2>Form</h2>
<form action="" method="post">
  First Name:
  <input type="text" name="Fname" maxlength="12" size="12"/> <br/>

  Last Name:
  <input type="text" name="Lname" maxlength="36" size="12"/> <br/>

  Gender:<br/>
    Male:<input type="radio" name="gender" value="Male"/><br/>
    Female:<input type="radio" name="gender" value="Female"/><br/>

  Favorite Food:<br/>
    Steak:<input type="checkbox" name="food[]" value="Steak"/><br/>
    Pizza:<input type="checkbox" name="food[]" value="Pizza"/><br/>
    Chicken:<input type="checkbox" name="food[]" value="Chicken"/><br/>

  <textarea wrap="physical" cols="20" name="quote" rows="5">Enter your favorite quote!</textarea><br/>

  Select a Level of Education:<br/>
  <select name="education">
    <option value="Jr.High">Jr.High</option>
    <option value="HighSchool">HighSchool</option>
    <option value="College">College</option>
  </select><br/>

  Select your favorite time of day:<br/>
  <select size="3" name="TofD">
    <option value="Morning">Morning</option>
    <option value="Day">Day</option>
    <option value="Night">Night</option>
  </select>
  <p><input type="submit" /></p>
</form>

<h2>JSON</h2>
<pre id="result">
</pre>
JavaScript:

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

$(function() {
    $('form').submit(function() {
        $('#result').text(JSON.stringify($('form').serializeObject()));
        return false;
    });
});

CSS:

form {
    line-height: 2em;
}
p {
    margin: 5px 0;
}
h2 {
    margin: 10px 0;
    font-size: 1.2em;
    font-weight: bold
}
#result {
    margin: 10px;
    background: #eee;
    padding: 10px;
    height: 40px;
    overflow: auto;
}


How to: sort arrays and data in PHP

How do I sort an array in PHP?
How do I sort a complex array in PHP?
How do I sort an array of objects in PHP?

Basic one dimensional arrays

$array = array(3, 5, 2, 8);
Applicable sort functions:

  • sort
  • rsort
  • asort
  • arsort
  • natsort
  • natcasesort
  • ksort
  • krsort
The difference between those is merely whether key-value associations are kept (the "a" functions), whether it sorts low-to-high or reverse ("r"), whether it sorts values or keys ("k") and how it compares values ("nat" vs. normal). See http://php.net/manual/en/array.sorting.php for an overview and links to further details.

Multi dimensional arrays, including arrays of objects

$array = array(
    array('foo' => 'bar', 'baz' => 42),
    array('foo' => ...,   'baz' => ...),
    ...
);
If you want to sort $array  by the key 'foo' of each entry, you need a custom comparison function. The above sort and related functions work on simple values that they know how to compare and sort. PHP does not simply "know" what to do with a complex value likearray('foo' => 'bar', 'baz' => 42) though; so you need to tell it.

To do that, you need to create a comparison function. That function takes two elements and must return 0 if these elements are considered equal, a value lower than 0 if the first value is lower and a value higher than 0 if the first value is higher. That's all that's needed:

function cmp(array $a, array $b) {
    if ($a['foo'] < $b['foo']) {
        return -1;
    } else if ($a['foo'] > $b['foo']) {
        return 1;
    } else {
        return 0;
    }
}

You then use one of these functions:

Again, they only differ in whether they keep key-value associations and sort by values or keys. Read their documentation for details.

Example usage:

usort($array, 'cmp');
usort will take two items from the array and call your cmp function with them. So cmp() will be called with $a as array('foo' => 'bar', 'baz' => 42) and $b as another array('foo' => ..., 'baz' => ...) The function then returns to usort which of the values was larger or whether they were equal. usort repeats this process passing different values for $a and $b until the array is sorted. The cmp function will be called many times, at least as many times as there are values in $array, with different combinations of values for $a and $b every time.

To get used to this idea, try this:

function cmp($a, $b) {
    echo 'cmp called with $a:', PHP_EOL;
    var_dump($a);
    echo 'and $b:', PHP_EOL;
    var_dump($b);
}
All you did was define a custom way to compare two items, that's all you need. That works with all sorts of values.

By the way, this works on any value, the values don't have to be complex arrays. If you have a custom comparison you want to do, you can do it on a simple array of numbers too.

Custom numeric comparisons

If you want to sort by the baz key, which is numeric, all you need to do is:

function cmp(array $a, array $b) {
    return $a['baz'] - $b['baz'];
}
Thanks to The PoWEr oF MATH this returns a value < 0, 0 or > 0 depending on whether $a is lower than, equal to or larger than $b.

NOTE: return $a['baz'] - $b['baz']; // to sort ASCENDING (1,2,3...) return $b['baz'] - $a['baz']; // to sort DESCENDING (9,8,7...)

Note that this won't work well for float values, since they'll be reduced to an int and lose precision. Use explicit -10 and 1 return values instead.

Objects

If you have an array of objects, it works the same way:

function cmp($a, $b) {
    return $a->baz - $b->baz;
}

Functions

You can do anything you need inside a comparison function, including calling functions:

function cmp(array $a, array $b) {
    return someFunction($a['baz']) - someFunction($b['baz']);
}

Strings

A shortcut for the first string comparison version:

function cmp(array $a, array $b) {
    return strcmp($a['foo'], $b['foo']);
}
strcmp does exactly what's expected of cmp here, it returns -10 or 1.

Sorting by multiple fields

If you want to sort primarily by foo, but if foo is equal for two elements sort by baz:

function cmp(array $a, array $b) {
    if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
        return $cmp;
    } else {
        return $a['baz'] - $b['baz'];
    }
}


For those familiar, this is equivalent to an SQL query with ORDER BY foo, baz.
Also see this very neat shorthand version and how to create such a comparison function dynamically for an arbitrary number of keys.

Sorting into a manual, static order

If you want to sort elements into a "manual order" like "foo", "bar", "baz":

function cmp(array $a, array $b) {
    static $order = array('foo', 'bar', 'baz');
    return array_search($a['foo'], $order) - array_search($b['foo'], $order);
}
For all the above, if you're using PHP 5.3 or higher (and you really should), use anonymous functions for shorter code and to avoid having another global function floating around:

usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });
That's how simple sorting a complex multi-dimensional array can be. Again, just think in terms of teaching PHP how to tell which of two items is "greater"; let PHP do the actual sorting.

Sorting one array based on another:

And then there's the peculiar array_multisort, which lets you sort one array based on another:

$array1 = array( 4,   6,   1);
$array2 = array('a', 'b', 'c');
The expected result here would be:

$array2 = array('c', 'a', 'b');  // the sorted order of $array1
Use array_multisort to get there:

array_multisort($array1, $array2);