Programing

Javascript에서 조건부로 객체를 멤버에 추가하는 방법은 무엇입니까?

lottogame 2020. 3. 24. 08:02
반응형

Javascript에서 조건부로 객체를 멤버에 추가하는 방법은 무엇입니까?


조건부로 추가 된 멤버로 객체를 만들고 싶습니다. 간단한 접근 방식은 다음과 같습니다.

var a = {};
if (someCondition)
    a.b = 5;

이제 더 관용적 인 코드를 작성하고 싶습니다. 나는 노력하고있다 :

a = {
    b: (someCondition? 5 : undefined)
};

그러나 지금 ba가치가 있는 멤버입니다 undefined. 이것은 원하는 결과가 아닙니다.

편리한 해결책이 있습니까?

최신 정보

여러 회원과 함께 일반적인 경우를 처리 할 수있는 솔루션을 찾고 있습니다.

a = {
  b: (conditionB? 5 : undefined),
  c: (conditionC? 5 : undefined),
  d: (conditionD? 5 : undefined),
  e: (conditionE? 5 : undefined),
  f: (conditionF? 5 : undefined),
  g: (conditionG? 5 : undefined),
 };

순수한 Javascript에서는 첫 번째 코드 스 니펫보다 관용적 인 것을 생각할 수 없습니다.

그러나 jQuery 라이브러리를 사용하는 것이 문제가 아닌 경우 설명서 에서 다음과 같이 $ .extend () 가 요구 사항을 충족해야합니다.

정의되지 않은 속성은 복사되지 않습니다.

따라서 다음과 같이 작성할 수 있습니다.

var a = $.extend({}, {
    b: conditionB ? 5 : undefined,
    c: conditionC ? 5 : undefined,
    // and so on...
});

그리고 (경우에 당신이 기대하는 결과를 얻을 수 conditionB있다 false, 그 다음 b에 존재하지 않습니다 a).


@InspiredJW가 ES5로 그렇게했다고 생각합니다. @ trincot이 지적했듯이 es6을 사용하는 것이 더 나은 방법입니다. 그러나 스프레드 연산자와 논리적 AND 단락 평가를 사용하여 설탕을 조금 더 추가 할 수 있습니다.

const a = {
   ...(someCondition && {b: 5})
}

EcmaScript2015를 사용하면 다음을 사용할 수 있습니다 Object.assign.

Object.assign(a, conditionB ? { b: 1 } : null,
                 conditionC ? { c: 2 } : null,
                 conditionD ? { d: 3 } : null);

var a, conditionB, conditionC, conditionD;
conditionC = true;
a = {};
Object.assign(a, conditionB ? { b: 1 } : null,
                 conditionC ? { c: 2 } : null,
                 conditionD ? { d: 3 } : null);

console.log(a);

일부 비고 :

더 간결한

(@Jamie는 지적 아웃이로) falsy 값이 더 자신의 열거 속성이 없기 때문에, (다음과 같이 상기 제 2 지점을 가지고 가서, 당신은 그것을 줄일 수 false, 0, NaN, null, undefined, ''제외 document.all) :

Object.assign(a, conditionB && { b: 1 },
                 conditionC && { c: 2 },
                 conditionD && { d: 3 });

var a, conditionB, conditionC, conditionD;
conditionC = "this is truthy";
conditionD = NaN; // falsy
a = {};
Object.assign(a, conditionB && { b: 1 },
                 conditionC && { c: 2 },
                 conditionD && { d: 3 });
console.log(a);


부울과 함께 스프레드 구문을 사용하는 것은 (여기에서 제안한 바와 같이) 유효한 구문이 아닙니다. 확산은 iterables 에만 사용할 수 있습니다 .

나는 다음을 제안한다.

const a = {
   ...(someCondition? {b: 5}: {} )
}

const obj = {
   ...(condition) && {someprop: propvalue},
   ...otherprops
}

라이브 데모 :

const obj = {
  ...(true) && {someprop: 42},
  ...(false) && {nonprop: "foo"},
  ...({}) && {tricky: "hello"},
}

console.log(obj);


Enhanced Object Properties를 사용하고 속성이 사실 인 경우에만 설정하는 방법은 다음과 같습니다.

[isConditionTrue() && 'propertyName']: 'propertyValue'

따라서 조건이 충족되지 않으면 선호하는 속성이 생성되지 않으므로 버릴 수 있습니다. 참조 : http://es6-features.org/#ComputedPropertyNames

업데이트 : 객체 리터럴 및 배열 ( http://2ality.com/2017/04/conditional-literal-entries.html ) 에 조건부로 항목을 추가하는 방법에 대한 블로그 기사에서 Axel Rauschmayer의 접근 방식을 따르는 것이 훨씬 좋습니다 .

const arr = [
  ...(isConditionTrue() ? [{
    key: 'value'
  }] : [])
];

const obj = {
  ...(isConditionTrue() ? {key: 'value'} : {})
};

나에게 많은 도움이되었다.


목표가 객체가 독립적으로 나타나고 하나의 중괄호 안에 있도록하는 것이라면 다음과 같이 해보십시오.

var a = new function () {
    if (conditionB)
        this.b = 5;

    if (conditionC)
        this.c = 5;

    if (conditionD)
        this.d = 5;
};

이 서버 측을 수행하려면 (jquery없이) lodash 4.3.0을 사용할 수 있습니다.

a = _.pickBy({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));

그리고 이것은 lodash 3.10.1을 사용하여 작동합니다.

a = _.pick({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));

이것은 오랫동안 대답했지만 다른 아이디어를 살펴보면 흥미로운 파생 상품을 생각해 냈습니다.

정의되지 않은 값을 동일한 속성에 할당하고 나중에 삭제

익명 생성자를 사용하여 객체를 만들고 정의되지 않은 멤버를 맨 끝에 제거 하는 동일한 더미 멤버에 항상 할당 하십시오. 이렇게하면 회원 당 한 줄 (너무 복잡하지는 않지만) + 한 줄에 추가 줄이 생깁니다.

var a = new function() {
    this.AlwaysPresent = 1;
    this[conditionA ? "a" : "undef"] = valueA;
    this[conditionB ? "b" : "undef"] = valueB;
    this[conditionC ? "c" : "undef"] = valueC;
    this[conditionD ? "d" : "undef"] = valueD;
    ...
    delete this.undef;
};

var a = {
    ...(condition ? {b: 1} : '') // if condition is true 'b' will be added.
}

조건에 따라 항목을 추가하는 가장 효율적인 방법이기를 바랍니다. 객체 리터럴 내에 조건부로 항목을 추가하는 방법에 대한 자세한 내용은.


나는 이것을 할 것이다

var a = someCondition ? { b: 5 } : {};

한 줄 코드 버전으로 편집


조건부로 멤버를 추가하는 첫 번째 방법은 완벽하게 좋습니다. 나는 가치 가있는 회원 b원하지 않는 것에 동의하지 않습니다 . 연산자 루프를 사용 하여 점검 을 추가하는 것은 간단 합니다 . 그러나 어쨌든 멤버 를 필터링하는 함수를 쉽게 작성할 수 있습니다 .aundefinedundefinedforinundefined

var filterUndefined = function(obj) {
  var ret = {};
  for (var key in obj) {
    var value = obj[key];
    if (obj.hasOwnProperty(key) && value !== undefined) {
      ret[key] = value;
    }
  }
  return ret;
};

var a = filterUndefined({
  b: (conditionB? 5 : undefined),
  c: (conditionC? 5 : undefined),
  d: (conditionD? 5 : undefined),
  e: (conditionE? 5 : undefined),
  f: (conditionF? 5 : undefined),
  g: (conditionG? 5 : undefined),
});

delete연산자를 사용 하여 객체를 제자리에서 편집 할 수도 있습니다 .


lodash 라이브러리를 사용하면 사용할 수 있습니다 _.omitBy을

var a = _.omitBy({
    b: conditionB ? 4 : undefined,
    c: conditionC ? 5 : undefined,
}, _.IsUndefined)

선택적인 요청이있을 때 편리합니다.

var a = _.omitBy({
    b: req.body.optionalA,  //if undefined, will be removed
    c: req.body.optionalB,
}, _.IsUndefined)

객체로 감싸기

이 같은 것은 조금 더 깨끗합니다

 const obj = {
   X: 'dataX',
   Y: 'dataY',
   //...
 }

 const list = {
   A: true && 'dataA',
   B: false && 'dataB',
   C: 'A' != 'B' && 'dataC',
   D: 2000 < 100 && 'dataD',
   // E: conditionE && 'dataE',
   // F: conditionF && 'dataF',
   //...
 }

 Object.keys(list).map(prop => list[prop] ? obj[prop] = list[prop] : null)

배열로 감싸기

또는 Jamie Hill의 방법을 사용하고 조건 목록이 매우 길면 ...구문을 여러 번 작성해야합니다 . 좀 더 깔끔하게 만들려면 배열로 래핑 한 다음 reduce()단일 객체로 반환하는 데 사용할 수 있습니다.

const obj = {
  X: 'dataX',
  Y: 'dataY',
  //...

...[
  true && { A: 'dataA'},
  false && { B: 'dataB'},
  'A' != 'B' && { C: 'dataC'},
  2000 < 100 && { D: 'dataD'},
  // conditionE && { E: 'dataE'},
  // conditionF && { F: 'dataF'},
  //...

 ].reduce(( v1, v2 ) => ({ ...v1, ...v2 }))
}

또는 map()기능을 사용하여

const obj = {
  X: 'dataX',
  Y: 'dataY',
  //...
}

const array = [
  true && { A: 'dataA'},
  false &&  { B: 'dataB'},
  'A' != 'B' && { C: 'dataC'},
  2000 < 100 && { D: 'dataD'},
  // conditionE && { E: 'dataE'},
  // conditionF && { F: 'dataF'},
  //...

 ].map(val => Object.assign(obj, val))

이것은 내가 얻을 수있는 가장 간결한 솔루션입니다.

var a = {};
conditionB && a.b = 5;
conditionC && a.c = 5;
conditionD && a.d = 5;
// ...

조건없이 정의되지 않은 모든 값을 추가 한 다음이를 사용 JSON.stringify하여 모두 제거 할 수 있습니다.

const person = {
  name: undefined,
  age: 22,
  height: null
}

const cleaned = JSON.parse(JSON.stringify(person));

// Contents of cleaned:

// cleaned = {
//   age: 22,
//   height: null
// }

lodash 라이브러리를 사용하면 사용할 수 있습니다 _.merge을

var a = _.merge({}, {
    b: conditionB ? 4 : undefined,
    c: conditionC ? 5 : undefined,
})
  1. conditionB가 false& conditionC가 true인 경우a = { c: 5 }
  2. 조건 b & conditionC 둘 경우 true, 다음a = { b: 4, c: 5 }
  3. 조건 b & conditionC 둘 경우 false, 다음a = {}

참고 : https://stackoverflow.com/questions/11704267/in-javascript-how-to-conditionally-add-a-member-to-an-object

반응형