Переменные JavaScript-назначения из кортежей - PullRequest
80 голосов
/ 22 декабря 2010

В других языках, таких как 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

Есть ли лучший способ симулировать кортежи Python в JavaScript 5?

Ответы [ 12 ]

97 голосов
/ 22 декабря 2010

В Javascript 1.7 добавлено деструктурированное назначение , которое позволяет вам делать то, что вам нужно.

function getTuple(){
   return ["Bob", 24];
}
var [a, b] = getTuple();
// a === "bob" , b === 24 are both true
47 голосов
/ 22 декабря 2010

Вы должны сделать это безобразно. Если вы действительно хотите что-то подобное, вы можете проверить CoffeeScript , который обладает этим и множеством других функций, которые делают его похожим на python реклама, но мне очень нравится.)

27 голосов
/ 22 февраля 2013

Вы можете сделать что-то похожее:

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

и затем ссылаться на имя и возраст как атрибуты

tuple.name 
tuple.age 
25 голосов
/ 06 ноября 2015

Эта функция «кортежа» в EcmaScript2015 называется деструктуризацией и скоро будет поддерживаться современными браузерами. В настоящее время поддерживает только Firefox и Chrome .

Но, эй, вы можете использовать транспортер .

Код выглядел бы так же хорошо, как и Python:

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

console.log(name)
console.log(age)
8 голосов
/ 25 ноября 2017

Замороженный массив ведет себя идентично кортежу 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 голосов
/ 12 марта 2015

Кортежи не поддерживаются в JavaScript

Если вы ищете неизменяемый список, Object.freeze () можно использовать для создания неизменяемого массива.

Метод Object.freeze () замораживает объект: предотвращает добавление к нему новых свойств;предотвращает удаление существующих свойств;и предотвращает изменение существующих свойств или их перечислимости, конфигурируемости или возможности записи.По сути, объект сделан эффективно неизменным.Метод возвращает замороженный объект.

Источник: Сеть разработчиков Mozilla - 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 ]
5 голосов
/ 22 декабря 2010

К сожалению, вы не можете использовать этот синтаксис назначения кортежей в (ECMA | Java) Script.

РЕДАКТИРОВАТЬ: Кто-то связался с Mozilla / JS 1.7 - это не будет работать кросс-браузер, но если это не требуется, то есть ваш ответ.

3 голосов
/ 09 февраля 2016

В качестве обновления к ответу министра, теперь вы можете сделать это с 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 голосов
/ 24 апреля 2012

Это не предназначено для реального использования в реальной жизни, просто интересное упражнение. См. Почему использование функции eval в JavaScript - плохая идея? для получения подробной информации.

Это самое близкое, что вы можете получить, не прибегая к конкретным расширениям:

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
})()

eval не поддерживается в Safari.

2 голосов
/ 21 мая 2017

Вы также можете иметь тип кортежа в 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 s, используемых как кортежи?Закодированные церковью кортежи имеют неизменный дизайн и, таким образом, предотвращают побочные эффекты, вызванные мутациями.Это помогает создавать более надежные приложения.Кроме того, проще рассуждать о коде, который различает Array s как тип коллекции (например, [a]) и кортежи как связанные данные различных типов (например, (a, b)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...