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?
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.)
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
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
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)
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 ]
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.
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.
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.
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"
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 à Array
s 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 Array
s 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)
).
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.
[a, b, c] = [2, 'momo', 7] // b === 'momo', c ===7 ...