18

I'm wondering if, and if how the following thing is working:

I have an array defined like the following:

var array = [
  {number: '1', value: 'one', context: 'someContext'}, 
  {number: '2', value: 'two', context: 'anotherContext'},
  ...
]

What I'm currently doing is pushing the elements into the array, so array.push({number: '1', value: 'one', context: 'someContext'}); and so on, with every array element.

Now this thing is extended: Say there's another key called 'content'. This key has a appropriate value, that is either undefined or a string. Now the question is: If I put the pushing in a function like this:

push(number, value, context, content) {
    array.push({
       number: number,
       value: value,
       context: context,
       content: content
    })
}

Is there anyway, I can make sure, that the key content is only added to the element, if the content (the function gets as parameter) is not null.

Of course I can modify function like that:

push(number, value, context, content) {
    if(!content) {
        array.push({
           number: number,
           value: value,
           context: context,
           content: content
       })
    } else {
        array.push({
           number: number,
           value: value,
           context: context
        })
   }
}

But the question is, if there is anyway to do this in the push function. I also thought about something like

array.push({
  number: number,
  value: value,
  context: context,
  content? content: content
})

So it would only be inserted if content is defined, but does this work, it didn't seem like, but maybe theres a mistake in my code.

dhilt
  • 18,707
  • 8
  • 70
  • 85
user5638730
  • 495
  • 2
  • 9
  • 22
  • `if(value == "null") return;` So you leave the function before the code is executed. If its not null then the `if` will be ignored and your code will continue to run. Just nest the that above array push, and call the function? Not sure if that's what you're thinking. – Brendan Aug 08 '16 at 19:54
  • I think with es6 the answers in this question https://stackoverflow.com/questions/281264/remove-empty-elements-from-an-array-in-javascript will help here, map an array then filter out null etc – ak85 Aug 02 '18 at 05:39

4 Answers4

16

If the objective isn't just to make code shorter, the most readable would be something like this, where you create the object, add the property if there is a value, and then push the object to the array.

push(number, value, context, content) {

    var o = {
        number  : number,
        value   : value,
        context : context
    }

    if (content !== null) o.content = content;

    array.push(o);
);

Here's an ES6 way to construct the object directly inside Array.push, and filter any that has null as a value.

function push(...arg) {
    array.push(['number','value','context','content'].reduce((a,b,i)=> {
        if (arg[i] !== null) a[b]=arg[i]; return a;
    }, {}))
}
Marcos Dimitrio
  • 6,651
  • 5
  • 38
  • 62
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • Unfortunately, with ES5 you have to be verbose. – Pavlo Aug 08 '16 at 19:55
  • 1
    @Pavlo - you don't really *have* to. There are many ways to "golf" this just using the `arguments` object, or maybe just passing in an object to the function begin with. The question is usually why make it more difficult then it is, unless one is in a "code golf" competition ? – adeneo Aug 08 '16 at 19:58
  • This looks good, I will try this out tomorrow. I'm using ECMA Script 6 btw. – user5638730 Aug 08 '16 at 19:58
  • @user5638730 in that case just shorten it - instead of `number : number`, you can just use `number`. It's exactly the same - ES6 made the `key: key` assignments less verbose. – VLAZ Aug 08 '16 at 19:59
  • What this answer changes except of code readability. I think nothing and for sure this is not solution but only code refactoring. – Maciej Sikora Aug 08 '16 at 20:11
  • 3
    @MaciejSikora - the OP has working code, and is basically asking if there is another way to write it? Surely changing the native prototypes isn't a solution for sane people either. – adeneo Aug 08 '16 at 20:14
  • @adeneo - functions with many attributes and ifs for single of them also is not a solution, for sure this is only answer for this particular problem and only single variable nullable capability. – Maciej Sikora Aug 08 '16 at 20:22
  • @adeneo Your first solution seems to work for me, the second somehow does not what I want, but thank you for giving me that solution :) – user5638730 Aug 09 '16 at 06:45
9

With Spread operator for object literals (ECMAScript 2018) it looks super easy:

const myPush = (number, value, context, content) =>
  array.push({
    ...{ number, value, context },
    ...content && { content }
  });
dhilt
  • 18,707
  • 8
  • 70
  • 85
7

If you are open to using ES2015, this can be done with Object.assign:

array.push(
  Object.assign(
    { number, value, context },
    content ? { content } : null
  )
);
Pavlo
  • 43,301
  • 14
  • 77
  • 113
0

It can be done by extending array:

//create Your own array object
myArray=function(){};
myArray.prototype=Object.create(Array.prototype);

//create method
myArray.prototype.pushDefined=function(obj){

  var newObj={};//create clean object 
  for (var key in obj){
  
    if (typeof obj[key]!='undefined' && obj[key]!=null){
      
      //this element is defined and is not null
      newObj[key]=obj[key];
      
    }
  }
  
  this.push(newObj);//push clean object without undefind properties

};

//tests
var arr=new myArray();
arr.pushDefined({ name:"John",surname:null});

console.log(arr[0]);

Or add this method to Array prototype:

Array.prototype.pushDefined=function(obj)... //this will be method in every array

I would not recommend changing original push method in Array because always think about other programmers who are using Array in this particular project.

Maciej Sikora
  • 19,374
  • 4
  • 49
  • 50
  • It looks like he only wants the `content` property treated specially, not all properties of the object. – Barmar Aug 08 '16 at 20:20
  • @Barmar This checks all possibilities, does it wrong? I think answers should be more predictable and showing better solution. – Maciej Sikora Aug 08 '16 at 20:23
  • This will leave out `value: null` and `context: null`. There's nothing in the question that says these should be omitted if they're empty. – Barmar Aug 08 '16 at 20:25
  • This is not a "better solution", in fact, it's a horrible solution that changes the native `Array.prototype`, which is probably the **number one** no-no in javascript since the dawn of time ? – adeneo Aug 08 '16 at 20:28
  • @adeneo yes You are right, i changed to Object.create(Array.prototype); to not change orginal prototype. Thanks! – Maciej Sikora Aug 08 '16 at 20:31