在Python 2和Python 3等其他语言中,您可以为元组变量定义和赋值,并检索它们的值,如下所示:
tuple = ("Bob", 24)
name, age = tuple
print(name) #name evaluates to Bob
print(age) #age evaluates to 24
JavaScript中有类似内容吗?或者我只需要用数组的丑陋方式来做:
tuple = ["Bob", 24]
name = tuple[0] //name Evaluates to Bob
age = tuple[1] //age Evaluates to 24
有没有更好的方法在JavaScript 5中模拟Python元组?
答案 0 :(得分:94)
Javascript 1.7添加了destructured assignment,它允许您基本上完成您的工作。
function getTuple(){
return ["Bob", 24];
}
var [a, b] = getTuple();
// a === "bob" , b === 24 are both true
答案 1 :(得分:47)
你必须以丑陋的方式去做。如果你真的想要这样的东西,你可以查看CoffeeScript,它有这个和许多其他功能,使它看起来更像python(抱歉让它听起来像一个广告,但我真的很喜欢。)
答案 2 :(得分:27)
你可以做类似的事情:
var tuple = Object.freeze({ name:'Bob', age:14 })
然后将名称和年龄称为属性
tuple.name
tuple.age
答案 3 :(得分:25)
这个"元组"它在EcmaScript2015中称为解构,很快就会得到最新浏览器的支持。目前,only Firefox and Chrome support it。
但是,嘿,你可以使用transpiler。
代码看起来和python一样好:
let tuple = ["Bob", 24]
let [name, age] = tuple
console.log(name)
console.log(age)
答案 4 :(得分:7)
冻结数组的行为与python元组相同:
const tuple = Object.freeze(["Bob", 24]);
let [name, age]; = tuple
console.debug(name); // "Bob"
console.debug(age); // 24
想要定义一个类
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
立即在所有最新浏览器中使用。
答案 5 :(得分:5)
不幸的是,您无法在(ECMA | Java)脚本中使用该元组赋值语法。
编辑:有人链接到Mozilla / JS 1.7 - 这不适用于跨浏览器,但如果不需要,那就是你的答案。答案 6 :(得分:5)
JavaScript不支持元组
如果您正在寻找一个不可变列表,可以使用Object.freeze()来使数组不可变。
Object.freeze()方法冻结一个对象:即阻止向其添加新属性;防止删除现有属性;并防止现有属性或其可枚举性,可配置性或可写性被更改。实质上,该对象实际上是不可变的。该方法返回被冻结的对象。
来源:Mozilla Developer Network - Object.freeze()
像往常一样分配数组,但使用'Object.freeze()
锁定它> tuple = Object.freeze(['Bob', 24]);
[ 'Bob', 24 ]
像使用常规数组一样使用值(不支持python多重赋值)
> name = tuple[0]
'Bob'
> age = tuple[1]
24
尝试分配新值
> tuple[0] = 'Steve'
'Steve'
但价值未改变
> console.log(tuple)
[ 'Bob', 24 ]
答案 7 :(得分:3)
这不是在现实生活中实际使用,只是一个有趣的练习。有关详细信息,请参阅Why is using the JavaScript eval function a bad idea?。
这是您可以获得的最接近特定供应商的扩展程序:
myArray = [1,2,3];
eval(set('a,b,c = myArray'));
辅助功能:
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(',');
}
证明它在任意范围内有效:
(function(){
myArray = [4,5,6];
eval(set('x,y,z = myArray'));
console.log(y); // prints 5
})()
Safari中不支持 eval
。
答案 8 :(得分:3)
作为部长回答的更新,您现在可以使用es2015执行此操作:
Select dbo.Function_Name(parameter_name)
Select dbo.Department_Employee_Count('HR')
答案 9 :(得分:2)
您也可以在Javascript中使用元组类型。只需用更高阶函数定义它(学术术语是教会编码):
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

请注意,Tuple
并未用作普通构造函数。该解决方案根本不依赖于原型系统,而仅仅依赖于更高阶的功能。
使用类似元组的Array
元组有什么优势?教会编码的元组在设计上是不可变的,因此可以防止由突变引起的副作用。这有助于构建更强大的应用程序。此外,更容易推理代码将Array
s区分为集合类型(例如[a]
),将元组区分为各种类型的相关数据(例如(a, b)
)。
答案 10 :(得分:1)
这是一个简单的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.
这是一个2元组,但是,您可以修改我的示例以支持3,4,5,6等元组。
答案 11 :(得分:-1)
[a, b, c] = [2, 'momo', 7] // b === 'momo', c ===7 ...
答案 12 :(得分:-1)
这是Matthew James Davis的答案的版本,其中添加了Python元组方法:
class Tuple extends Array {
constructor(...items) {
super(...items);
Object.freeze(this);
}
toArray() {
return [...this];
}
toString() {
return '('+super.toString()+')';
}
count(item) {
var arr = this.toArray();
var result = 0;
for(var i = 0; i < arr.length; i++) {
if(arr[i] === item) {
result++;
}
}
return result;
}
}
let tuple = new Tuple("Jim", 35);
let [name,age] = tuple;
console.log("tuple:"+tuple)
console.log("name:"+name)
console.log("age:"+age)
答案 13 :(得分:-1)
我做了一个很好的元组实现。此解决方案允许进行数组解构以及基本的类型检查。
const Tuple = (function() {
function Tuple() {
// Tuple needs at least one element
if (arguments.length < 1) {
throw new Error('Tuple needs at least one element');
}
const args = { ...arguments };
// Define a length property (equal to the number of arguments provided)
Object.defineProperty(this, 'length', {
value: arguments.length,
writable: false
});
// Assign values to enumerable properties
for (let i in args) {
Object.defineProperty(this, i, {
enumerable: true,
get() {
return args[+i];
},
// Checking if the type of the provided value matches that of the existing value
set(value) {
if (typeof value !== typeof args[+i]) {
throw new Error('Cannot assign ' + typeof value + ' on ' + typeof args[+i]);
}
args[+i] = value;
}
});
}
// Implementing iteration with Symbol.iterator (allows for array destructuring as well for...of loops)
this[Symbol.iterator] = function() {
const tuple = this;
return {
current: 0,
last: tuple.length - 1,
next() {
if (this.current <= this.last) {
let val = { done: false, value: tuple[this.current] };
this.current++;
return val;
} else {
return { done: true };
}
}
};
};
// Sealing the object to make sure no more values can be added to tuple
Object.seal(this);
}
// check if provided object is a tuple
Tuple.isTuple = function(obj) {
return obj instanceof Tuple;
};
// Misc. for making the tuple more readable when printing to the console
Tuple.prototype.toString = function() {
const copyThis = { ...this };
const values = Object.values(copyThis);
return `(${values.join(', ')})`;
};
// conctat two instances of Tuple
Tuple.concat = function(obj1, obj2) {
if (!Tuple.isTuple(obj1) || !Tuple.isTuple(obj2)) {
throw new Error('Cannot concat Tuple with ' + typeof (obj1 || obj2));
}
const obj1Copy = { ...obj1 };
const obj2Copy = { ...obj2 };
const obj1Items = Object.values(obj1Copy);
const obj2Items = Object.values(obj2Copy);
return new Tuple(...obj1Items, ...obj2Items);
};
return Tuple;
})();
const SNAKE_COLOR = new Tuple(0, 220, 10);
const [red, green, blue] = SNAKE_COLOR;
console.log(green); // => 220