78
var foo = [{ bar: 1, baz: [1,2,3] }, { bar: 2, baz: [4,5,6] }];

var filtered = $.grep(foo, function(v){
    return v.bar === 1;
});

console.log(filtered);

http://jsfiddle.net/98EsQ/

Is there any way to modify a certain objects property (like the one I'm filtering out above) without creating new arrays and/or objects?

Desired result: [{ bar: 1, baz: [11,22,33] }, { bar: 2, baz: [4,5,6] }]

Johan
  • 34,157
  • 52
  • 174
  • 280
  • @squint I was looking for a method which allowed me to "point" at a certain object and let me alter it (either in ES or jQuery). But I guess I have to do it manually with a foreach :) – Johan May 22 '13 at 12:38

11 Answers11

61

.map with spread (...) operator

var result = foo.map(el => el.bar == 1 ? {...el, baz: [11,22,33]} : el);

Piotrek
  • 1,012
  • 6
  • 13
43

Sure, just change it:

With jQuery's $.each:

$.each(foo, function() {
    if (this.bar === 1) {
        this.baz[0] = 11;
        this.baz[1] = 22;
        this.baz[2] = 33;
        // Or: `this.baz = [11, 22, 33];`
    }
});

With ES5's forEach:

foo.forEach(function(obj) {
    if (obj.bar === 1) {
        obj.baz[0] = 11;
        obj.baz[1] = 22;
        obj.baz[2] = 33;
        // Or: `obj.baz = [11, 22, 33];`
    }
});

...or you have other looping options in this other SO answer.

T.J. Crowder
  • 959,406
  • 173
  • 1,780
  • 1,769
32

You can use find and change its property.

let foo = [{ bar: 1, baz: [1,2,3] }, { bar: 2, baz: [4,5,6] }];

let obj = foo.find(f=>f.bar==1);
if(obj)
  obj.baz=[2,3,4];
console.log(foo);
Suraj Rao
  • 28,850
  • 10
  • 94
  • 99
  • this is useful only if you know you'll always have a single match – Gie Sep 28 '21 at 14:21
  • 1
    @AdiG true. If you are looking at multiple it would be better to use `map` like [this answer](https://stackoverflow.com/a/45341784/4826457) – Suraj Rao Sep 28 '21 at 14:23
10

Without jQuery and backwards compatibility

for (var i = 0; i < foo.length; i++) {
    if (foo[i].bar === 1) {
        foo[i].baz = [11,12,13];
    }
}
David Barker
  • 14,197
  • 3
  • 45
  • 76
10

We can also achieve this by using Array's map function:

 foo.map((obj) => {
   if(obj.bar == 1){
     obj.baz[0] = 11;
     obj.baz[1] = 22;
     obj.baz[2] = 33;
   }
 })
Mahima Agrawal
  • 1,187
  • 12
  • 13
7
    const objArr = [
        {prop1: 'value1', prop2: 'value11'},
        {prop1: 'value2', prop2: 'value22'},
        {prop1: 'value3', prop2: 'option33'},
        {prop1: 'value4', prop2: 'option44'}
    ]

    const newObjArr = objArr.map(obj => {
            if (['value1', 'value2'].includes(obj.prop1)) {
                return {...obj, prop1: 'newValue'}
            }
            return obj
        }
    )
    
    // const responseGotten = [
    //     { prop1: 'newValue', prop2: 'value11' },
    //     { prop1: 'newValue', prop2: 'value22' },
    //     { prop1: 'value3', prop2: 'option33' },
    //     { prop1: 'value4', prop2: 'option44' }
    // ]
gildniy
  • 2,550
  • 27
  • 19
3
$.each(foo,function(index,value)
{
    if(this.bar==1)
    {
this.baz[0] = 11;
        this.baz[1] = 22;
        this.baz[2] = 33;
    }

});

but for loop is faster than $.each so u can try to use

for(var i=0; i <foo.length; i++)
{

if(foo[i].bar==1)
{
//change the code
}
}
SivaRajini
  • 6,785
  • 19
  • 77
  • 121
3

But before opting any of the mentioned techniques please keep in mind the performance challenges associated with each of the approach.

Object iterate For-In, average: ~240 microseconds.

Object iterate Keys For Each, average: ~294 microseconds.

Object iterate Entries For-Of, average: ~535 microseconds.

Reference - 3 JavaScript Performance Mistakes You Should Stop Doing

Divyanshu Rawat
  • 3,569
  • 1
  • 33
  • 42
2

you can play around:

const tasks = [ { id: 1, done: false }, { id: 2, done: false } ]
const completed_task = { id: 1, done: true }

const markCompleted = (tasks, task) => {
  const index = tasks.findIndex(t => t.id === task.id);
  tasks.splice(index, 1);
  tasks.push(task);
  return tasks;
}

console.log(tasks)
console.log(markCompleted(tasks, completed_task))

EDIT

to avoid index change:

const markCompleted = (tasks, task) => {
      const index = tasks.findIndex(t => t.id === task.id);
      tasks[index] = task;
      return tasks;
    }
Muhammed Moussa
  • 3,365
  • 28
  • 19
2

You can modify the array by using simple for loop

var foo = [{ bar: 1, baz: [1,2,3] }, { bar: 2, baz: [4,5,6] }];
for(i = 0;i < foo.length;i++){
  //Here your confition for which item you went to edit
 if(foo[i].bar == 1){
    //Here you logic for update property
  foo[i].baz= [1,11,22]
 }
}
console.log(foo);
Kalpesh Dabhi
  • 659
  • 5
  • 14
1

You can make use of filter function of javascript.

obj = [
    {inActive:false, id:1},
    {inActive:false, id:2},
    {inActive:false, id: 3}
];
let nObj = obj.filter(ele => {
    ele.inActive = true;
    return ele;
});

console.log(nObj);
  • Wouldn't map be more semantically correct? You are not really filtering anything, since your intent the whole time is to return every element. Also, you're not really altering the object, either, just creating a copy that is changed. I think OP specifically said no new objects. – Chris Strickland Nov 25 '21 at 03:04