Javascript equivalent of PHP's list()
Asked Answered
D

9

72

Really like that function.

$matches = array('12', 'watt');
list($value, $unit) = $matches;

Is there a Javascript equivalent of that?

Damiondamita answered 23/12, 2009 at 18:11 Comment(12)
What's wrong with a standard approach var value = matches[0]; var unit = matches[1]; Decided
Well, that's not very concise, is it?Dearly
I never felt list() to be useful and the above just yells object to me var power = { 'unit': 'watt', 'amount': 12 }Molybdous
It's very ugly and long. I think list() makes code more readable.Damiondamita
@Gordon: Not many functions returns objects, like ''.match()Damiondamita
@Znarkus: I'd still create a ValueObject out of the array, but feel free to do it differently :)Molybdous
@Gordon: list(power.unit, power.amount) = weirdStringToParse.match(massiveRegEx)Damiondamita
@Znarkus var getPowerFromWeirdString = function(weirdString) {var power = weirdString.match(massiveRegEx); return {'unit': power[0], 'amount': power[1] }; };Molybdous
Haha Gordon, you could wrap my solution in a function also :)Damiondamita
@Tchalvak adding external dependencies is never more coincise.Tideland
Here's another way of accomplishing this: https://mcmap.net/q/276114/-javascript-alternativesMarkettamarkey
PHP's list() is handy if you want to swap variable values without the need of a temporary variable: list($b, $a) = array($a, $b);Gon
H
63

There is, in 'newer' versions of Javascript: Destructuring assignment - Javascript 1.7. It's probably only supported in Mozilla-based browsers, and maybe in Rhino.

var a = 1;  
var b = 3;  

[a, b] = [b, a];  

EDIT: actually it wouldn't surprise me if the V8 Javascript library (and thus Chrome) supports this. But don't count on it either Now supported in all modern browsers(except IE, of course).

Hid answered 23/12, 2009 at 18:16 Comment(5)
Neat! I really like all the cool stuff they've put into the new versions of Javascript! Just feels like we wont be able to use them for ages..Damiondamita
Year 2015 and still unsupported by V8.Lycia
Firefox supports it since version 2 back in 2006. It's still not supported by V8/Chrome in 2015. Chrome is the new IE.Piddling
Be careful using this still in 2018; IE never supported it, and many people still use it. Useful for judging compatibility: kangax.github.io/compat-table/es6Julie
Reporting from 2019 March. This is working in Chrome 72 (64-bit).Polygamist
A
20

try this:

matches = ['12', 'watt'];
[value, unit] = matches; 
Abundance answered 15/6, 2011 at 22:22 Comment(0)
E
19

ES6 does support this directly now via array destructuring.

const matches = ['12', 'watt'];
const [value, unit] = matches;
Entryway answered 27/11, 2015 at 12:2 Comment(1)
As of mid-2019 this is the best answer. The accepted answer will throw "[variable] is not defined (no-undef)" warnings in many linters. This corrects for that. Note that you can also do array deconstructing in for...of loopsBigg
I
4

This is my solution for using List/Explode on Javascript. Fiddle Working Example

First the implementation :

var dateMonth = "04/15";
dateMonth.split("/").list("month","day", "year");
month == "04";
day == "15";
year == null;

It also allows for scoping the new generated variables :

var scoped = (function()
{ 
    var dateMonth = "07/24/2013"; 
    dateMonth.split("/").list("month","day", "year", this);
    this.month == "07";
    this.day == "24";
    this.year == "2013";
})();

This was accomplished by modifying an the Array prototype.

Array.prototype.list = function()
{
    var 
        limit = this.length,
        orphans = arguments.length - limit,
        scope = orphans > 0  && typeof(arguments[arguments.length-1]) != "string" ? arguments[arguments.length-1] : window 
    ;

    while(limit--) scope[arguments[limit]] = this[limit];

    if(scope != window) orphans--;

    if(orphans > 0)
    {
        orphans += this.length;
        while(orphans-- > this.length) scope[arguments[orphans]] = null;  
    }  
}
Interphase answered 24/7, 2013 at 17:55 Comment(4)
I'm sticking with my solution. If you try something like : matches = ['12', 'watt']; [value, unit] = matches; Or function () { var [year, month] = $(this).val().split("/"); In Chrome, it will throw an error : "ReferenceError: Invalid left-hand side in assignment"Interphase
Using window as a default object is a very bad idea.Solvency
@Solvency he only defaults to it. You can provide an object as the last parameter and it will use that.Morphinism
@Interphase love this little script, works perfectly for me. Very nice that you account for labels that exceed the dataMorphinism
T
2

There is a experimental implementation of list() by PHPJS here:
https://github.com/kvz/phpjs/blob/master/_experimental/array/list.js

Tracheostomy answered 24/3, 2011 at 10:42 Comment(1)
The second link in this post is dead (404 - This is not the web page you are looking for).Debidebilitate
I
2

CoffeeScript offers destructuring assignment with the syntax:

[a, b] = someFunctionReturningAnArray()

This is pretty much identical to the feature offered in very new JavaScript versions. However, CoffeeScript produces compiled JS that is compatible even with IE6's JavaScript engine, and therefore it's a good option if compatibility is vital.

Illyes answered 11/12, 2012 at 3:15 Comment(0)
C
2

Since most JavaScript implementations don't yet support that feature, you could simply do it in a more JavaScript-like fashion:

function list(){
    var args = arguments;
    return function(array){
        var obj = {};
        for(i=0; i<args.length; i++){
            obj[args[i]] = array[i];
        }
        return obj;
    };
}

Example:

var array = ['GET', '/users', 'UserController'];
var obj = {};

obj = list('method', 'route', 'controller')(array);

console.log(obj.method);        // "GET"
console.log(obj.route);         // "/users"
console.log(obj.controller);    // "UserController"

Check the fiddle


An alternative is to add a list-method to Array.prototype (even I wouldn't recommend it):

Array.prototype.list = function(){
    var i, obj = {};
    for(i=0; i<arguments.length; i++){
        obj[arguments[i]] = this[i];
    }
    // if you do this, you pass to the dark side `,:,´
    this.props = obj;
    return obj;
};

Example:

/**
 * Example 1: use Array.prototype.props
 */

var array = ['GET', '/users', 'UserController'];
array.list('method', 'route', 'controller');

console.log(array.props.method);        // "GET"
console.log(array.props.route);         // "/users"
console.log(array.props.controller);    // "UserController"

/**
 * Example 2: use the return value
 */

var array = ['GET', '/users', 'UserController'];
var props = array.list('method', 'route', 'controller');

console.log(props.method);      // "GET"
console.log(props.route);       // "/users"
console.log(props.controller);  // "UserController"

Check the fiddle for that one

Cheekbone answered 27/11, 2015 at 11:2 Comment(0)
M
0

This is my hack at it; as short as I could get it without writing a function to do it. Gotta be careful of the scope of "this" though:

list = ["a","b","c"];
vals = [1,2,3];
for(var i in vals)this[list[i]]=vals[i];
console.log(a,b,c);

Good enough for a laugh. I still assign each variable one at a time:

a=vals[0];
b=vals[1];
c=vals[2];

It's much shorter this way. Besides, if you've got a bunch of variables they should probably be kept in the array, or even better they should be properties of a closure, instead of declaring them all separately.

Mojave answered 22/3, 2015 at 4:3 Comment(0)
S
-2
function list(fn,array){
    if(fn.length && array.length){
        for(var i=0;i<array.length;i++){
            var applyArray = [];
            for(var j=0;j<array[i].length;j++){
                fn[j] = array[i][j];
                applyArray.push(fn[j]);
            }
        fn.apply(this,applyArray);
       }
   }
}

Example:

//array array mixture for composure
var arrayMixture = [ ["coffee","sugar","milk"], ["tea","sugar","honey"] ];
//call our function


list(function(treat,addin,addin2){
    console.log("I like "+treat+" with " + addin + " and " + addin2);
},arrayMixture);


//output:
//I like coffee with sugar and milk
//I like tea with sugar and honey
Schiedam answered 10/9, 2015 at 21:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.