튜플에서 JavaScript 변수 할당


101

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 튜플을 시뮬레이션하는 더 좋은 방법이 있습니까?

업데이트 : 새 프로젝트의 경우 CoffeeScript보다 선호되어야하는 ES6에 대한 답변을 참조하십시오.


12
JavaScript에서 변수를 선언하는 것을 잊지 마십시오 :var tuple, name, age;
Šime Vidas dec.

3
var name=tuple[0], age=tuple[1]; 타이핑이 조금 더 많지만 추한 것은 과장 일 수 있습니다.
Brent Bradburn 2013 년

답변:


122

Javascript 1.7 은 본질적으로 원하는 것을 할 수 있도록 해체 된 할당 을 추가했습니다 .

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

5
이것은 표준 기반 자바 스크립트가 아니라 Mozilla 관련 확장입니다.
ninjagecko 2012

14
@ninjagecko : "JavaScript"는 Mozilla의 구현이며, 구조화 할당은 향후 ecmascript 표준의 일부가 될 것입니다
Bergi

65
이제 실제로 ES6의 일부입니다.
Pier Paolo Ramon

10
몇 년 동안 내 대답은 기술적으로 정확 해졌지만 정확하고 도움이되지는 않았습니다. 예이!
pc1oad1etter

49

추악한 방식으로해야합니다. 당신이 경우 정말 이런 걸 원하는, 당신은 체크 아웃 할 수있다 커피 스크립트 그와 더 파이썬처럼 보이게 다른 기능의 전체 많이 가지고, (미안 그것 같이 정말 광고 같은 소리하고 있지만합니다.)


흠, 이것은 꽤 흥미 롭습니다. 자바 스크립트가 명백한 튜플 지원을 제공하지 않는 것 같고, 함수형 프로그래밍의 강렬한 기간에서 튜플에 대한 요구를 개발하기 때문에이 시나리오에서 직접 실행했습니다. 나는 또한 이것을 발견했지만 작동하는지 확실하지 않지만 튜플 지원 측면에서도 좋아 보였습니다 . cs.umd.edu/projects/PL/arrowlets/api-tuples.xhtml . 확실히 CoffeeScript를 살펴 보겠습니다.
9codeMan9 2013

29

비슷한 작업을 수행 할 수 있습니다.

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

이름과 나이를 속성으로

tuple.name 
tuple.age 

5
나는 반대표를 던지지는 않지만 기술적으로 이것은 올바르지 않습니다. 객체가 선언 된 후에도 tuple.name 및 tuple.age 값을 변경 (즉, 변경) 할 수 있습니다. 정의에 따라 불변 유형은 정의 된 후에 변경할 수 없습니다. 매개 변수와 해당 값을 한 번만 선언 할 수있는 읽기 전용 유형과 같습니다.
Evan Plaice

4
@EvanPlaice 변경 가능성이 문제인 경우 다음을 사용할 수 있습니다 Object.freeze().tuple = Object.freeze({ name:'Bob', age:14 })
canon

@canon 동의합니다. 이것이 전체 스레드에서 유일하게 수용 가능한 / 올바른 접근 방식 일 것입니다. 불행히도 mcm의 대답은 객체를 고정하지 않으므로 여전히 변경 가능합니다.
Evan Plaice 2014 년

@EvanPlaice 변경 가능성 문제가 어디에서 왔는지 알 수 없습니다. 원본 Python 예제에서는 튜플이 변경 불가능하지 않습니다!
Daniel Buckmaster 2015 년

@DanielBuckmaster Python에서 목록과 튜플의 차이점은 목록은 변경 가능하지만 튜플은 그렇지 않다는 것입니다. docs.python.org/2/tutorial/… 참조 . 생성 후 객체에서 Object.freeze ()를 호출하지 않는 한 모든 JS 데이터 구조가 변경 가능하기 때문에 튜플은 JavaScript에서 기본적으로 지원되지 않습니다.
Evan Plaice 2015 년

27

이 "튜플"기능은 EcmaScript2015에서 구조 분해라고하며 곧 최신 브라우저에서 지원 될 예정입니다. 당분간 Firefox와 Chrome 만 지원합니다 .

하지만 트랜스 파일러를 사용할 수 있습니다 .

코드는 파이썬만큼 멋지게 보일 것입니다.

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

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

2
미래 독자들에게 :이 기능은 크롬 49 이후 크롬에서 지원됩니다 (Mozilla 문서에 따름). Mozilla 문서를 사용하여 호환성을 확인할 수도 있습니다. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Jamie

13

고정 된 배열은 파이썬 튜플과 동일하게 작동합니다.

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

모든 최신 브라우저에서 오늘 작동합니다.


그냥 const로 설정할 수 없습니까? const는 불변입니다.
Mark A

3
아니요. const는 재 할당 할 수 없습니다. const tuple = [ "Jim", 35]; 튜플 = [ "James", 35]. const tuple = [ "Jim", 35]; tuple [0] = "제임스"; 따라서 불변이 아닙니다.
매튜 제임스 데이비스

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 ]

참고로 튜플은 ES6에서 최고 수준의 지원을받을 것입니다. 진정한 네이티브 튜플 (예 : 이종 시퀀스)도 속도를 향상시킵니다.
Evan Plaice 2015 년

5

불행히도 (ECMA | Java) Script에서는 해당 튜플 할당 구문을 사용할 수 없습니다.

편집 : Mozilla / JS 1.7에 연결된 사람-이것은 브라우저 간 작동하지 않지만 필요하지 않은 경우 답변이 있습니다.


3

이것은 실제 생활에서 실제로 사용하기위한 것이 아니라 단지 흥미로운 연습 일뿐입니다. 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에서는 지원되지 않습니다.


5
+1 슈퍼 영리 것에 대해, 지금까지 실제 생활에서 이것을 사용하지 않는 P는하지만
Jamund 퍼거슨

3

장관의 답변에 대한 업데이트로 이제 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


당신이 ES2015하기 전에이 작업을 수행 할 수없는 이유 아무 이유 또한이가 OP의 질문에 대답하지 않는 ... 없다, 그는 destructuring 요청
ThatWeirdo

3

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).


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 등의 튜플을 지원하도록 내 예제를 수정할 수 있습니다.


사실 이것은 t-uple이 아니라 한 쌍입니다.
Pier Paolo Ramon

tuple인스턴스는 변경 가능한, 그래서 기술적으로 튜플이 아니다. 증명 변경 tuple.Item1 = "Steve"console.log()위해 출력.
Evan Plaice 2015 년

1
찾아 주셔서 감사합니다. Tuple을 불변으로 만들기 위해 예제를 수정했습니다.
Faris Zacina 2015 년

임의의 길이를 지원하도록 어떻게 수정합니까?
aij

이는 영업 이익의 질문에 대답하지 않습니다, 그는 destructuring 요청
ThatWeirdo

0

다음은 Python 튜플 메서드가 추가 된 Matthew James Davis의 답변 버전입니다.

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)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.