web-gelistirme-sc.com

Javascript'te koşullu olarak bir nesneye nasıl üye eklenir?

Koşullu eklenmiş bir üye ile bir nesne yaratmak istiyorum . Basit yaklaşım:

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

Şimdi daha deyimsel bir kod yazmak istiyorum. Deniyorum:

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

Ama şimdi, b, değeri a olan undefined üyesidir. Bu istenen sonuç değil.

Kullanışlı bir çözüm var mı?

Güncelle

Genel olayı birkaç üyeyle halledebilecek bir çözüm arıyorum.

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),
 };
181
viebel

Saf Javascript'te, ilk kod snippet'inizden daha aptalca bir şey düşünemiyorum.

Bununla birlikte, jQuery kütüphanesini kullanmak söz konusu değilse, $ .extend () , gereksinimlerinizi karşılamalıdır çünkü dokümantasyonun dediği gibi

Tanımsız özellikler kopyalanmaz.

Bu nedenle, şunları yazabilirsiniz:

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

Beklediğiniz sonuçları elde edin (conditionBfalse ise, ba içinde bulunmayacaktır).

81

@InspiredJW'nin ES5 ile yaptığını ve trincot'un işaret ettiği gibi es6 kullanmak daha iyi bir yaklaşım. Fakat spread operatörünü ve mantıklı AND kısa devre değerlendirmesini kullanarak biraz daha şeker ekleyebiliriz:

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

EcmaScript2015 ile Object.assign kullanabilirsiniz:

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

Bazı açıklamalar:

Daha da özlü

İkinci noktayı daha ileriye götürmek gerekirse, @Jamie'nin belirttiği gibi, aşağıdaki gibi kısaltabilirsiniz, çünkü sahte değerlerin kendi numaralandırılabilir özellikleri yoktur (false, 0, NaN, nullundefined, '' ) hariç, 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);

74
trincot

Geliştirilmiş Nesne Özellikleri'ni kullanmaya ne dersiniz ve özelliği yalnızca gerçektirse ayarlayın;

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

Yani koşul yerine getirilmezse, tercih edilen özelliği yaratmaz ve bu nedenle onu atabilirsiniz . Bkz: http://es6-features.org/#ComputedPropertyNames

UPDATE: Axel Rauschmayer'in blog makalesinde, nesne değişmezleri ve dizilerin içine koşullu olarak girdiler ekleme konusundaki yaklaşımını takip etmek daha da iyidir ( http://2ality.com/2017/04/conditional- literal-input.html ):

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

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

Bana çok yardımcı oldu.

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

Boolean ile yayılma sözdizimini kullanmak (burada önerildiği gibi) geçerli sözdizimi değildir. Spread sadece yinelemeli ile kullanılabilir.

Aşağıdakileri öneriyorum:

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

Amaç, nesnenin kendi kendine yeten görünmesini ve bir küme ayracı içinde olmasını sağlamaksa, şunu deneyebilirsiniz:

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

    if (conditionC)
        this.c = 5;

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

Bu sunucu tarafını yapmak istiyorsanız (jquery olmadan), lodash 4.3.0'ı kullanabilirsiniz:

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

Ve bu lodash 3.10.1 kullanarak çalışır

a = _.pick({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));
5
Mickl
var a = {
    ...(condition ? {b: 1} : '') // if condition is true 'b' will be added.
}

İnşallah bu koşulu temel alan bir girdi eklemek için en etkili yoldur .. __ Nesne değişmezleri içine koşullu olarak girdiler ekleme hakkında daha fazla bilgi için.

4
Madhankumar

Bu uzun zamandır cevaplandırılmış, ancak başka türevlere bakarak ilginç bir türev buldum:

Tanımsız değerleri aynı özelliğe atayın ve daha sonra silin

Nesnenizi isimsiz bir kurucu kullanarak yaratın ve tanımsız üyeleri daima en sonunda kaldırdığınız aynı dummy üyesine atayın. Bu, size üye başına + 1 ek satır için tek bir satır (çok karmaşık değil umarım) verecektir.

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;
};
4
Robert Koritnik

Tüm tanımsız değerlerinizi koşulsuz olarak ekleyebilir ve ardından hepsini kaldırmak için JSON.stringify öğesini kullanabilirsiniz:

const person = {
    name:undefined,
    age:22,
    height:null
}
const cleaned = JSON.parse(JSON.stringify(person));

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

Bunu yapardım

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

Bir satır kod sürümüyle düzenlendi

1
InspiredJW

Lodash kütüphanesini kullanarak _.omitBy

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

Bu isteğe bağlı olan istekleriniz olduğunda kullanışlıdır

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

Bir nesneye sarın

Böyle bir şey biraz temizleyici

 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)

Diziye sar

Veya Jamie Hill'in yöntemini kullanmak ve çok uzun bir koşul listesine sahip olmak istiyorsanız, o zaman ... sözdizimini birden çok kez yazmanız gerekir. Biraz daha temiz hale getirmek için, onları bir diziye sarabilir, ardından tek bir nesne olarak geri döndürmek için reduce() işlevini kullanabilirsiniz.

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

Veya map() işlevini kullanarak

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))
0
Dedy Abdillah

Üyeleri koşullu olarak eklemek için ilk yaklaşımınızın mükemmel olduğunu düşünüyorum. b değeri olan a üyesi undefined sahibi olmak istemediğime katılıyorum. undefined işleci ile for döngüsünün kullanımıyla bir in denetimi ekleyecek kadar basit. Ama yine de, undefined üyelerini filtrelemek için kolayca bir fonksiyon yazabilirsiniz.

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),
});

Nesneyi yerinde düzenlemek için delete işlecini de kullanabilirsiniz.

0
Yunchi