1

Given an Object s as

s = {
   a:1,
   b:2
}

I can define a new object t with fields depending on the contents of s,

say something like

t = {
   d: s.a ? 1 : 2
}

then the field d value depends on s.a ( Value of d depends on whether s.a is defined or not).

How can I exclude a field in an object depending o the value of s? , Something like

t = {
   d: s.a ? 1 : undefined
}

This doesn't work though ...

I know this can be done with a couple of if else but I'm looking for an elegant solution/ oneliners

My object is pretty huge, so I do not want to do something like

t = s.a? {
       d: 1 
    } : {}

EDIT I've seen a wide variety of solutions, I'm looking at a solution that is a oneliner/has minimum changes and is readable. Something like an idiomatic javascript/ecmascript 6

EDIT The duplicate found here seems to be for javascript and does give correct answers to this question. I'm hoping the new ecmascript might have a newer solution to this question

Malice
  • 1,457
  • 16
  • 32

4 Answers4

1

Try this:

var t = $.extend({}, {
    d: s.a ? 1 : undefined
});
ice 13
  • 333
  • 4
  • 17
  • Isn't this same as what I specified in the question ? Or am I missing somehting ? – Malice Sep 06 '17 at 10:21
  • You didn't use the extend method. If you use it it will work. – ice 13 Sep 06 '17 at 10:23
  • If that is right, Why does it disappear on extend.. ? – Malice Sep 06 '17 at 10:29
  • Maybe I misunderstood your question. I thought you want to have only properties with values in t variable. – ice 13 Sep 06 '17 at 10:32
  • You got it spot on!, But my question was more theoretical, Why does i need to move it to another object using extend, for the `undefined` to really become *the* ``'undefined'`` ? – Malice Sep 06 '17 at 10:36
  • I guess that's how JavaScript works. It has many interesting facts. Like the result of `2.1 * 2.2` (you can check it in console). – ice 13 Sep 06 '17 at 10:38
  • That sure is wierd. Is there a better way ? It sill costs me a function call and a copy :-) – Malice Sep 06 '17 at 10:47
  • I think you can do it with JavaScript 2015 (or ES6) and TypeScript but it's not yet compatible with all browsers. We usually use it with Angular and compile it to ES5. Might not be worth for you yet. – ice 13 Sep 06 '17 at 10:50
  • I'm indeed looking for a ES6 solution :-) – Malice Sep 06 '17 at 10:52
1

You didn't really tell what problem you're trying to solve, but generally there are several solutions:

Generate t from a

This is good if the properties are supposed to be equal in value. Because your property names differ, you'll need to map them:

const source = {
   a: 10,
   b: 12
}
const propertyNameMap = {
   a: "alpha",
   b: "beta"
}
const target = {};
for(let i in source) {
    if(source.hasOwnProperty(i) && propertyNameMap[i]) {
        target[propertyNameMap[i]] = source[i];
    }
}

Property getters

If properties need unique conversions, but are dependent, you can define a getter for the target object. Note that this has obvious performance implications and isn't really much better than just generating the values statically, unless they change in time:

// eg. if alpha maps to ASCII letter:
Object.defineProperty(target, "alpha", {
    get: function() {return String.fromCharCode(a.a);},
    enumerable: true
});
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
0
let s = {
    a : 1
}

let data = {};
if(!!s.a) {
    data.a = s.a;
}

console.log(data);
Alex
  • 1,692
  • 13
  • 10
0

You can use Object.assign() and if there is s.a property it will add properties of new object otherwise it won't do anything.

var s = {a:1,b:2}
var t = {}

Object.assign(t, s.a ? {d: 1} : null)
console.log(t)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176