Переменные JavaScript-назначения из кортежей

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

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

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

а затем укажите имя и возраст в качестве атрибутов

tuple.name 
tuple.age 

Ответ 4

Эта функция "tuple" называется деструктуризацией в EcmaScript2015 и вскоре будет поддерживаться современными браузерами. Пока что поддерживает только Firefox и Chrome.

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

Код будет выглядеть так же хорошо, как python:

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

console.log(name)
console.log(age)

Ответ 5

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

EDIT: Кто-то, связанный с Mozilla/JS 1.7 - это не будет работать с кросс-браузером, но если это не требуется, ответьте.

Ответ 6

Кортежи не поддерживаются в 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 ]

Ответ 7

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

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

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.

Ответ 8

В качестве ответа министра, вы можете сделать это с помощью 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

Ответ 9

Вот простая реализация Jupp; 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 immutable.

Это 2-кортеж, однако вы можете изменить мой пример, чтобы поддерживать 3,4,5,6 и т.д.

Ответ 10

В 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

Ответ 11

[a, b, c] = [2, 'momo', 7]  // b === 'momo', c ===7 ...

Ответ 12

Замороженный массив ведет себя одинаково с корнем 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

Работает сегодня во всех последних браузерах.