web-dev-qa-db-fra.com

Assignations de variables JavaScript à partir de Tuples

Dans d'autres langages tels que Python 2 et Python 3, vous pouvez définir et affecter des valeurs à une variable Tuple et récupérer leurs valeurs comme suit:

Tuple = ("Bob", 24)
name, age = Tuple
print(name)           #name evaluates to Bob
print(age)            #age evaluates to 24

Y a-t-il quelque chose de similaire en JavaScript? Ou dois-je simplement le faire de la manière laide avec un tableau:

Tuple = ["Bob", 24]
name = Tuple[0]       //name Evaluates to Bob
age = Tuple[1]        //age Evaluates to 24

Existe-t-il un meilleur moyen de simuler des n-uplets Python dans JavaScript 5?

73
Karl

Vous devez le faire de la manière laide. Si vous vraiment voulez quelque chose comme ça, vous pouvez regarder CoffeeScript , qui a cela et beaucoup d'autres fonctionnalités qui font que ça ressemble plus à du python (désolé de le faire sonner comme une publicité , mais je l’aime vraiment beaucoup.)

48
Gabi Purcaru

Javascript 1.7 ajouté assignation déstructurée qui vous permet de faire essentiellement ce que vous voulez.

function getTuple(){
   return ["Bob", 24];
}
var [a, b] = getTuple();
// a === "bob" , b === 24 are both true
92
pc1oad1etter

Vous pouvez faire quelque chose de similaire: 

var Tuple = Object.freeze({ name:'Bob', age:14 })

puis se référer au nom et à l'âge en tant qu'attributs 

Tuple.name 
Tuple.age 
26
monika mevenkamp

Ce "tuple" est appelé "déstructuration" dans EcmaScript2015 et sera bientôt supporté par les navigateurs récents Pour le moment, seuls Firefox et Chrome le supportent

Mais bon, vous pouvez utiliser un transpiler .

Le code aurait l'air aussi beau que python:

let Tuple = ["Bob", 24]
let [name, age] = Tuple

console.log(name)
console.log(age)
23
Adrian

Les tuples ne sont pas supportés en JavaScript

Si vous cherchez une liste immuable, Object.freeze () peut être utilisé pour rendre un tableau immuable.

La méthode Object.freeze () gèle un objet: cela empêche l'ajout de nouvelles propriétés; empêche les propriétés existantes d'être supprimées; et empêche les propriétés existantes, ou leur énumérabilité, configurabilité ou possibilité d'écriture, d'être modifiées. En substance, l'objet est effectivement rendu immuable. La méthode retourne l'objet en cours de gel.

Source: Réseau de développeurs Mozilla - Object.freeze ()

Assigne un tableau comme d'habitude mais verrouille-le en utilisant 'Object.freeze ()

> Tuple = Object.freeze(['Bob', 24]);
[ 'Bob', 24 ]

Utilisez les valeurs comme vous le feriez avec un tableau standard (la multi-affectation python n'est pas prise en charge)

> name = Tuple[0]
'Bob'
> age = Tuple[1]
24

Tentative d'attribution d'une nouvelle valeur

> Tuple[0] = 'Steve'
'Steve'

Mais la valeur n'est pas modifiée

> console.log(Tuple)
[ 'Bob', 24 ]
5
Evan Plaice

Malheureusement, vous ne pouvez pas utiliser cette syntaxe d'affectation Tuple dans le script (ECMA | Java).

EDIT: Quelqu'un lié à Mozilla/JS 1.7 - cela ne fonctionnerait pas multi-navigateur, mais si cela n’est pas nécessaire, voici la réponse.

5
meder omuraliev

Un tableau figé se comporte de manière identique à un tuple en python:

const Tuple = Object.freeze(["Bob", 24]);
let [name, age]; = Tuple
console.debug(name); // "Bob"
console.debug(age); // 24

Être chic et définir une classe

class Tuple extends Array { 
  constructor(...items) { 
    super(...items); 
    Object.freeze(this);
  } 
}

let Tuple = new Tuple("Jim", 35);
let [name, age] = Tuple;
console.debug(name); // Jim
console.debug(age); // 35
Tuple = ["Bob", 24]; // no effect 
console.debug(name); // Jim
console.debug(age); // 25

Fonctionne aujourd'hui dans tous les navigateurs les plus récents.

4

Ceci n'est pas destiné à être réellement utilisé dans la vie réelle, juste un exercice intéressant. Voir Pourquoi l'utilisation de la fonction JavaScript eval est-elle une mauvaise idée? pour plus de détails.

C’est le plus proche que vous puissiez obtenir sans recourir à des extensions spécifiques au fournisseur:

myArray = [1,2,3];
eval(set('a,b,c = myArray'));

Fonction d'assistance:

function set(code) {
    var vars=code.split('=')[0].trim().split(',');
    var array=code.split('=')[1].trim();
    return 'var '+vars.map(function(x,i){return x+'='+array+'['+i+']'}).join(',');
}

La preuve que cela fonctionne dans une portée arbitraire:

(function(){
    myArray = [4,5,6];
    eval(set('x,y,z = myArray'));
    console.log(y);  // prints 5
})()

eval n'est pas pris en charge dans Safari.

3
ninjagecko

Pour mettre à jour la réponse du ministre, vous pouvez maintenant le faire avec es2015:

function Tuple(...args) {
  args.forEach((val, idx) => 
    Object.defineProperty(this, "item"+idx, { get: () => val })
  )
}


var t = new Tuple("a", 123)
console.log(t.item0) // "a"
t.item0 = "b"
console.log(t.item0) // "a"

https://jsbin.com/fubaluwimo/edit?js,console

3
Zach Dahl

Vous pouvez aussi avoir un type de tuple en Javascript. Définissez-le simplement avec des fonctions d'ordre supérieur (le terme académique est le codage de l'église):

const Tuple = (...args) => {
  const Tuple = f => f(...args);
  return Object.freeze(Object.assign(Tuple, args));
};

const get1 = tx => tx((x, y) => x);

const get2 = tx => tx((x, y) => y);

const bimap = f => g => tx => tx((x, y) => Tuple(f(x), g(y)));

const toArray = tx => tx((...args) => args);

// aux functions

const inc = x => x + 1;
const toUpperCase = x => x.toUpperCase();

// mock data

const pair = Tuple(1, "a");

// application

console.assert(get1(pair) === 1);
console.assert(get2(pair) === "a");

const {0:x, 1:y} = pair;
console.log(x, y); // 1 a

console.log(toArray(bimap(inc) (toUpperCase) (pair))); // [2, "A"]

const map = new Map([Tuple(1, "a"), Tuple(2, "b")]);
console.log(map.get(1), map.get(2)); // a b

Veuillez noter que Tuple n'est pas utilisé en tant que constructeur normal. La solution ne repose pas du tout sur le système prototype, mais uniquement sur des fonctions d'ordre supérieur.

Quels sont les avantages des tuples par rapport à Arrays utilisés comme des tuples? Les n-uplets encodés par Church sont immuables par conception et empêchent ainsi les effets secondaires causés par les mutations. Cela aide à construire des applications plus robustes. En outre, il est plus facile de raisonner sur le code qui distingue Arrays en tant que type de collection (par exemple, [a]) et des nuplets en tant que données associées de différents types (par exemple, (a, b)).

2
user6445533

Voici une simple implémentation de Javascript Tuple:

var Tuple = (function () {
   function Tuple(Item1, Item2) {
      var item1 = Item1;
      var item2 = Item2;
      Object.defineProperty(this, "Item1", {
          get: function() { return item1  }
      });
      Object.defineProperty(this, "Item2", {
          get: function() { return item2  }
      });
   }
   return Tuple;
})();

var Tuple = new Tuple("Bob", 25); // Instantiation of a new Tuple
var name = Tuple.Item1; // Assignment. name will be "Bob"
Tuple.Item1 = "Kirk"; // Will not set it. It's immutable.

Ceci est un 2-Tuple, cependant, vous pouvez modifier mon exemple pour prendre en charge 3,4,5,6 etc.

1
Faris Zacina
[a, b, c] = [2, 'momo', 7]  // b === 'momo', c ===7 ...
0
drordk