458

The code below comes from jQuery UI Autocomplete:

var projects = [
    {
        value: "jquery",
        label: "jQuery",
        desc: "the write less, do more, JavaScript library",
        icon: "jquery_32x32.png"
    },
    {
        value: "jquery-ui",
        label: "jQuery UI",
        desc: "the official user interface library for jQuery",
        icon: "jqueryui_32x32.png"
    },
    {
        value: "sizzlejs",
        label: "Sizzle JS",
        desc: "a pure-JavaScript CSS selector engine",
        icon: "sizzlejs_32x32.png"
    }
];

For example, I want to change the desc value of jquery-ui. How can I do that?

Additionally, is there a faster way to get the data? I mean give the object a name to fetch its data, just like the object inside an array? So it would be something like jquery-ui.jquery-ui.desc = ....

4
  • You would have to transform the array into a Javascript object in order to use the syntax projects["jquery-ui"].desc. Would that be worth the effort only to get nicer syntax? Commented Jan 14, 2011 at 10:26
  • I've updated my solution with your latest question. And you can use the "projects.jquery-ui.desc" notation. Commented Jan 14, 2011 at 10:28
  • ** ↑ aston means you can use that notation if the object structure is changed as per his answer below. (Not with the OP's existing example structure.) Commented Oct 27, 2020 at 22:04
  • For new people, just use .find() it's a method for the array and is very useful in this case. See abe kur's answer on this. Commented Mar 2, 2021 at 3:22

34 Answers 34

587

It is quite simple

  • Find the index of the object using findIndex method.
  • Store the index in variable.
  • Do a simple update like this: yourArray[indexThatyouFind]

//Initailize array of objects.
let myArray = [
  {id: 0, name: "Jhon"},
  {id: 1, name: "Sara"},
  {id: 2, name: "Domnic"},
  {id: 3, name: "Bravo"}
],
    
//Find index of specific object using findIndex method.    
objIndex = myArray.findIndex(obj => obj.id == 1);

//Log object to Console.
console.log("Before update: ", myArray[objIndex])

//Update object's name property.
myArray[objIndex].name = "Laila"

//Log object to console again.
console.log("After update: ", myArray[objIndex])

Sign up to request clarification or add additional context in comments.

4 Comments

it will mutate myArray.
Yes, But if you do not want to mutate. [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], myArray.slice(objIndex + 1))]
@UmairAhmed Shouldnt the above code be [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], ...myArray.slice(objIndex + 1))] ? I think ur missing the second ellipses.
In my case it's perfect, I was looking for a way to get an object into an object array, then change one of its properties. I need the object to mutate because it's watched by a Vue.js component
206

You have to search in the array like:

function changeDesc( value, desc ) {
   for (var i in projects) {
     if (projects[i].value == value) {
        projects[i].desc = desc;
        break; //Stop this loop, we found it!
     }
   }
}

and use it like

var projects = [ ... ];
changeDesc ( 'jquery-ui', 'new description' );

UPDATE:

To get it faster:

var projects = {
   jqueryUi : {
      value:  'lol1',
      desc:   'lol2'
   }
};

projects.jqueryUi.desc = 'new string';

(In according to Frédéric's comment you shouldn't use hyphen in the object key, or you should use "jquery-ui" and projects["jquery-ui"] notation.)

4 Comments

Is there much faster way to get the data? I mean give the object a name to fetch its data.Just like the object inside array.So,can I used in that way : jquery-ui.jquery-ui.desc = ....
your update won't work because of the hyphen - in the object name. You would have to write "jquery-ui": {} and projects["jquery-ui"].desc respectively.
look at the abe kur's answer, that is the right, this and anothers are long
For new people, just use .find() it's a method for the array and is very useful in this case. See abe kur's answer on this.
201

The best solution, thanks to ES6.

This returns a new array with a replaced description for the object that contains a value equal to "jquery-ui".

const newProjects = projects.map(p =>
  p.value === 'jquery-ui'
    ? { ...p, desc: 'new description' }
    : p
);

7 Comments

@FrederikoCesar not in all cases, iterating over each object costs more than slicing the array and inject the new object using spread operator
what if you want to change the value on the fly? Without creating another var? Best way is the index method: const targetIndex = summerFruits.findIndex(f=>f.id===3);
this is great and short. could you write out how you would update two values at the same time from the? the shorthand notation is sure hard to understand for me. ? : are if else whats "..."
@SgtPepperAut maybe this way: proj.map(p => ['jquery-ui', 'other-value'].includes(p.value) ? { ...p, desc: 'new-description' } : p )
For new people, just use .find() it's a method for the array and is very useful in this case. See abe kur's answer on this.
|
108

Using map is the best solution without using extra libraries.(using ES6)

const state = [
{
    userId: 1,
    id: 100,
    title: "delectus aut autem",
    completed: false
},
{
    userId: 1,
    id: 101,
    title: "quis ut nam facilis et officia qui",
    completed: false
},
{
    userId: 1,
    id: 102,
    title: "fugiat veniam minus",
    completed: false
},
{
    userId: 1,
    id: 103,
    title: "et porro tempora",
    completed: true
}]

const newState = state.map(obj =>
    obj.id === "101" ? { ...obj, completed: true } : obj
);

2 Comments

this solution was provided already: stackoverflow.com/a/51718190/6543875
This solution only works when ternary operator is used. Isn't is possible to use this method without ternary operator like --> const newState = state.map(obj => [{ ...obj, completed: true }] ); ?
96

ES6 way, without mutating original data.

var projects = [
{
    value: "jquery",
    label: "jQuery",
    desc: "the write less, do more, JavaScript library",
    icon: "jquery_32x32.png"
},
{
    value: "jquery-ui",
    label: "jQuery UI",
    desc: "the official user interface library for jQuery",
    icon: "jqueryui_32x32.png"
}];

//find the index of object from array that you want to update
const objIndex = projects.findIndex(obj => obj.value === 'jquery-ui');

// Make sure to avoid incorrect replacement
// When specific item is not found
if (objIndex === -1) {
  return;
}

// make new object of updated object.   
const updatedObj = { ...projects[objIndex], desc: 'updated desc value'};

// make final new array of objects by combining updated object.
const updatedProjects = [
  ...projects.slice(0, objIndex),
  updatedObj,
  ...projects.slice(objIndex + 1),
];

console.log("original data=", projects);
console.log("updated data=", updatedProjects);

Comments

37

You can use $.each() to iterate over the array and locate the object you're interested in:

$.each(projects, function() {
    if (this.value == "jquery-ui") {
        this.desc = "Your new description";
    }
});

Comments

24

given the following data, we want to replace berries in the summerFruits list with watermelon.

const summerFruits = [
{id:1,name:'apple'}, 
{id:2, name:'orange'}, 
{id:3, name: 'berries'}];

const fruit = {id:3, name: 'watermelon'};

Two ways you can do this.

First approach:

//create a copy of summer fruits.
const summerFruitsCopy = [...summerFruits];

//find index of item to be replaced
const targetIndex = summerFruits.findIndex(f=>f.id===3); 

//replace the object with a new one.
summerFruitsCopy[targetIndex] = fruit;

Second approach: using map, and spread:

const summerFruitsCopy = summerFruits.map(fruitItem => 
fruitItem .id === fruit.id ? 
    {...summerFruits, ...fruit} : fruitItem );

summerFruitsCopy list will now return an array with updated object.

1 Comment

The first method is best. No need to move to another var and then back. On the fly method. I up voted your solution.
23

you can use .find so in your example

   var projects = [
            {
                value: "jquery",
                label: "jQuery",
                desc: "the write less, do more, JavaScript library",
                icon: "jquery_32x32.png"
            },
            {
                value: "jquery-ui",
                label: "jQuery UI",
                desc: "the official user interface library for jQuery",
                icon: "jqueryui_32x32.png"
            },
            {
                value: "sizzlejs",
                label: "Sizzle JS",
                desc: "a pure-JavaScript CSS selector engine",
                icon: "sizzlejs_32x32.png"
            }
        ];

let project = projects.find((p) => {
    return p.value === 'jquery-ui';
});

project.desc = 'your value'

1 Comment

While this functionally does the same thing, findIndex performs significantly better than find. If your source array is large, I recommend findIndex instead. Refer to the answer with the most upvotes.
23

It's easily can be accomplished with underscore/lodash library:

  _.chain(projects)
   .find({value:"jquery-ui"})
   .merge({desc: "new desc"}).value();

Docs:
https://lodash.com/docs#find
https://lodash.com/docs#merge

3 Comments

What if 'jquery-ui' is not found by the find function?
Property 'find' does not exist on type 'LoDashExplicitArrayWrapper'
The result of such sequences must be unwrapped with _#value. lodash.com/docs/4.17.4#chain .value()
21

This is another answer involving find. This relies on the fact that find:

  • iterates through every object in the array UNTIL a match is found
  • each object is provided to you and is MODIFIABLE

Here's the critical Javascript snippet:

projects.find( function (p) {
    if (p.value !== 'jquery-ui') return false;
    p.desc = 'your value';
    return true;
} );

Here's an alternate version of the same Javascript:

projects.find( function (p) {
    if (p.value === 'jquery-ui') {
        p.desc = 'your value';
        return true;
    }
    return false;
} );

Here's an even shorter (and somewhat more evil version):

projects.find( p => p.value === 'jquery-ui' && ( p.desc = 'your value', true ) );

Here's a full working version:

  let projects = [
            {
                value: "jquery",
                label: "jQuery",
                desc: "the write less, do more, JavaScript library",
                icon: "jquery_32x32.png"
            },
            {
                value: "jquery-ui",
                label: "jQuery UI",
                desc: "the official user interface library for jQuery",
                icon: "jqueryui_32x32.png"
            },
            {
                value: "sizzlejs",
                label: "Sizzle JS",
                desc: "a pure-JavaScript CSS selector engine",
                icon: "sizzlejs_32x32.png"
            }
        ];

projects.find( p => p.value === 'jquery-ui' && ( p.desc = 'your value', true ) );

console.log( JSON.stringify( projects, undefined, 2 ) );

1 Comment

Wow, this is some piece of magic you just did there!
19

you need to know the index of the object you are changing. then its pretty simple

projects[1].desc= "new string";

Comments

19

const users = [
  { name: "Alex", age: 25 },
  { name: "John", age: 32 },
];

const newUsers = users.map((user) => ({
  ...user,
  age: user.age + 5, // just for example
}));

// newUsers = [
// {name:"Alex" , age:30},
// {name:"John , age:37}
// ]

1 Comment

somehow missing the () after the arrow function raised an error for me so this one looks to be the most correct answer for ES6
13

I think this way is better

const index = projects.findIndex(project => project.value==='jquery-ui');
projects[index].desc = "updated desc";

1 Comment

in your findIndex you're assigning a value instead of comparing
9
let users = [
    {id: 1, name: 'Benedict'},
    {id: 2, name: 'Myles'},
    {id: 3, name: 'Happy'},
]

 users.map((user, index) => {
 if(user.id === 1){
  users[index] = {id: 1, name: 'Baba Benny'};    
 }
 
 return user
})


console.log(users)

What this code does is map over the object and then match the desired with if statement,

if(user.id === 1) 

once there is match somewhere use its index to swap

 users[index] = {id: 1, name: 'Baba Benny'};

the object in the array and then return the modified array

5 Comments

instead of writing the code, please explain what is happening there
There’s 29 answers already. The accepted answer has 183 upvotes. Why do we need another answer? What is this answer offering that’s not already covered by the previous 29 answers?
@JeremyCaney This is because there so many ways to skin a cat, also by provide readers with verities of code flow they can pick one or mix and match the approaches
@mwangaben return value will be user, not users
@sayinmehmet47 thanks for pointing it out i have already fixed
6

Change value with conditions using for each loop

projects.forEach((p,index)=>{
    if(index === 1){
       p.value = "Updated jquery-ui"
    }
})

Comments

4

// using higher-order functions to avoiding mutation
var projects = [
            {
                value: "jquery",
                label: "jQuery",
                desc: "the write less, do more, JavaScript library",
                icon: "jquery_32x32.png"
            },
            {
                value: "jquery-ui",
                label: "jQuery UI",
                desc: "the official user interface library for jQuery",
                icon: "jqueryui_32x32.png"
            },
            {
                value: "sizzlejs",
                label: "Sizzle JS",
                desc: "a pure-JavaScript CSS selector engine",
                icon: "sizzlejs_32x32.png"
            }
        ];

// using higher-order functions to avoiding mutation
index = projects.findIndex(x => x.value === 'jquery-ui');
[... projects.slice(0,index), {'x': 'xxxx'}, ...projects.slice(index + 1, projects.length)];

2 Comments

this ... before projects are necessary?
@lazzy_ms the ... is known as the spread operator. google it :)
4

You can use map function --

const answers = this.state.answers.map(answer => {
  if(answer.id === id) return { id: id, value: e.target.value }
  return answer
})

this.setState({ answers: answers })

Comments

4

try using forEach(item,index) helper

var projects = [
    {
        value: "jquery",
        label: "jQuery",
        desc: "the write less, do more, JavaScript library",
        icon: "jquery_32x32.png"
    },
    {
        value: "jquery-ui",
        label: "jQuery UI",
        desc: "the official user interface library for jQuery",
        icon: "jqueryui_32x32.png"
    },
    {
        value: "sizzlejs",
        label: "Sizzle JS",
        desc: "a pure-JavaScript CSS selector engine",
        icon: "sizzlejs_32x32.png"
    }
];

let search_to_change = 'jquery'

projects.forEach((item,index)=>{
   if(item.value == search_to_change )
      projects[index].desc = 'your description ' 
})

Comments

2

Here is a nice neat clear answer. I wasn't 100% sure this would work but it seems to be fine. Please let me know if a lib is required for this, but I don't think one is. Also if this doesn't work in x browser please let me know. I tried this in Chrome IE11 and Edge they all seemed to work fine.

    var Students = [
        { ID: 1, FName: "Ajay", LName: "Test1", Age: 20},
        { ID: 2, FName: "Jack", LName: "Test2", Age: 21},
        { ID: 3, FName: "John", LName: "Test3", age: 22},
        { ID: 4, FName: "Steve", LName: "Test4", Age: 22}
    ]

    Students.forEach(function (Student) {
        if (Student.LName == 'Test1') {
            Student.LName = 'Smith'
        }
        if (Student.LName == 'Test2') {
            Student.LName = 'Black'
        }
    });

    Students.forEach(function (Student) {
        document.write(Student.FName + " " + Student.LName + "<BR>");
    });

Output should be as follows

Ajay Smith

Jack Black

John Test3

Steve Test4

Comments

2

Assuming you wanted to run a bit more complicated codes during the modification, you might reach for an if-else statement over the ternary operator approach

// original 'projects' array;
var projects = [
    {
        value: "jquery",
        label: "jQuery",
        desc: "the write less, do more, JavaScript library",
        icon: "jquery_32x32.png"
    },
    {
        value: "jquery-ui",
        label: "jQuery UI",
        desc: "the official user interface library for jQuery",
        icon: "jqueryui_32x32.png"
    },
    {
        value: "sizzlejs",
        label: "Sizzle JS",
        desc: "a pure-JavaScript CSS selector engine",
        icon: "sizzlejs_32x32.png"
    }
];
// modify original 'projects' array, and save modified array into 'projects' variable
projects = projects.map(project => {
// When there's an object where key 'value' has value 'jquery-ui'
    if (project.value == 'jquery-ui') {

// do stuff and set a new value for where object's key is 'value'
        project.value = 'updated value';

// do more stuff and also set a new value for where the object's key is 'label', etc.
        project.label = 'updated label';

// now return modified object
        return project;
    } else {
// just return object as is
        return project;
    }
});

// log modified 'projects' array
console.log(projects);

Comments

2

We can change in the following way

const oldArray = [{username: gopal, age: 20}, {username: gopi, age: 21}]
const obj = {username: gopal, age: 25}
const result = oldArray.map(d => d.username === 'gopi' ? d.age = obj.age : d)

Comments

1

We can also use Array's map function to modify object of an array using Javascript.

function changeDesc(value, desc){
   projects.map((project) => project.value == value ? project.desc = desc : null)
}

changeDesc('jquery', 'new description')

1 Comment

this will return [null, object with the updated value, null]
1

The power of javascript destructuring

const projects = [
  {
    value: 'jquery',
    label: 'jQuery',
    desc: 'the write less, do more, JavaScript library',
    icon: 'jquery_32x32.png',
    anotherObj: {
      value: 'jquery',
      label: 'jQuery',
      desc: 'the write less, do more, JavaScript library',
      icon: 'jquery_32x32.png',
    },
  },
  {
    value: 'jquery-ui',
    label: 'jQuery UI',
    desc: 'the official user interface library for jQuery',
    icon: 'jqueryui_32x32.png',
  },
  {
    value: 'sizzlejs',
    label: 'Sizzle JS',
    desc: 'a pure-JavaScript CSS selector engine',
    icon: 'sizzlejs_32x32.png',
  },
];

function createNewDate(date) {
  const newDate = [];
  date.map((obj, index) => {
    if (index === 0) {
      newDate.push({
        ...obj,
        value: 'Jquery??',
        label: 'Jquery is not that good',
        anotherObj: {
          ...obj.anotherObj,
          value: 'Javascript',
          label: 'Javascript',
          desc: 'Write more!!! do more!! with JavaScript',
          icon: 'javascript_4kx4k.4kimage',
        },
      });
    } else {
      newDate.push({
        ...obj,
      });
    }
  });

  return newDate;
}

console.log(createNewDate(projects));

Comments

0

Find the index first:

function getIndex(array, key, value) {
        var found = false;
        var i = 0;
        while (i<array.length && !found) {
          if (array[i][key]==value) {
            found = true;
            return i;
          }
          i++;
        }
      }

Then:

console.log(getIndex($scope.rides, "_id", id));

Then do what you want with this index, like:

$scope[returnedindex].someKey = "someValue";

Note: please do not use for, since for will check all the array documents, use while with a stopper, so it will stop once it is found, thus faster code.

Comments

0

You can create your specific function like the below, then use that everywhere you need.

var each    = (arr, func) => 
                Array.from(
                    (function* (){
                        var i = 0;
                        for(var item of arr)
                            yield func(item, i++);
                    })()
                );

Enjoy..

1 Comment

Welcome to the community, if you explain what is going on and how it is working, then obviously everyone can Enjoy..
0
upsert(array, item) { 
        const i = array.findIndex(_item => _item.id === item.id);
        if (i > -1) {
            let result = array.filter(obj => obj.id !== item.id);
            return [...result, item]
        }
        else {
            return [...array, item]
        };
    }

Comments

-1

to update multiple items with the matches use:

_.chain(projects).map(item => {
      item.desc = item.value === "jquery-ui" ? "new desc" : item.desc;
      return item;
    })

Comments

-1

Try this code. it uses jQuery grep function

array = $.grep(array, function (a) {
    if (a.Id == id) {
        a.Value= newValue;
    }
    return a;
});

Comments

-1

Here i am using angular js. In javascript you can use for loop to find.

    if($scope.bechval>0 &&$scope.bechval!=undefined)
    {

                angular.forEach($scope.model.benhmarkghamlest, function (val, key) {
                $scope.model.benhmarkghamlest[key].bechval = $scope.bechval;

            });
    }
    else {
        alert("Please sepecify Bechmark value");
    }

Comments

-1

The easiest way is to do this

    var projects = [
{
    
    
    value: "jquery",
    label: "jQuery",
    desc: "the write less, do more, JavaScript library",
    icon: "jquery_32x32.png"
},
{
    value: "jquery-ui",
    label: "jQuery UI",
    desc: "the official user interface library for jQuery",
    icon: "jqueryui_32x32.png"
}];

projects.find(data => data.value === "jquery").label ="xxxx"

console.log("------------>",projects)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.