¿Cómo cambiar el valor del objeto que está dentro de una matriz usando JavaScript o jQuery?

201

El siguiente código proviene de 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"
    }
];

Por ejemplo, quiero cambiar el valor desc de jquery-ui . ¿Cómo puedo hacer eso?

Además, ¿hay una forma más rápida de obtener los datos? Quiero decir, ¿darle al objeto un nombre para obtener sus datos, al igual que el objeto dentro de una matriz? Entonces sería algo comojquery-ui.jquery-ui.desc = ....

qinHaiXiang
fuente
Tendría que transformar la matriz en un objeto Javascript para usar la sintaxis projects["jquery-ui"].desc. ¿Valdría la pena el esfuerzo solo para obtener una sintaxis más agradable?
Frédéric Hamidi
He actualizado mi solución con su última pregunta. Y puede usar la notación "projects.jquery-ui.desc".
Aston

Respuestas:

135

Tienes que buscar en la matriz como:

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

y úsalo como

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

ACTUALIZAR:

Para hacerlo más rápido:

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

projects.jqueryUi.desc = 'new string';

(De acuerdo con el comentario de Frédéric, no debe usar guiones en la clave de objeto, o debe usar la notación "jquery-ui" y proyectos ["jquery-ui"]).

Aston
fuente
¿Hay una forma mucho más rápida de obtener los datos? Me refiero a dar un nombre al objeto para obtener sus datos. Al igual que el objeto dentro de la matriz. Entonces, ¿puedo usar de esa manera: jquery-ui.jquery-ui.desc = ....
qinHaiXiang
2
su actualización no funcionará debido al guión -en el nombre del objeto. Tendrías que escribir "jquery-ui": {}y projects["jquery-ui"].descrespectivamente.
Frédéric Hamidi
Gracias, no lo sabía.
Aston
mirar a la respuesta de la abe kur, que es el derecho, y este anothers son largas
stackdave
231

Es bastante simple

  • Encuentra el índice del objeto usando el findIndexmétodo.
  • Almacenar el índice en variable.
  • Haga una actualización simple como esta: 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])

Umair Ahmed
fuente
2
¿Alguna razón para el doble ()en el findIndexmétodo?
Terkhos
3
mutará myArray.
Bimal Grg
1
Sí, pero si no quieres mutar. [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], myArray.slice(objIndex + 1))]
Umair Ahmed
1
@UmairAhmed ¿No debería ser el código anterior [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], ...myArray.slice(objIndex + 1))]? Creo que te faltan las segundas elipses.
Craig
1
me encanta lo limpio que es esto!
tdelam
57

Manera ES6 , sin mutar los datos originales.

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 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);
Bimal Grg
fuente
54

La mejor solución, gracias a ES6.

Esto devuelve una nueva matriz con una descripción reemplazada para el objeto que contiene un valor igual a "jquery-ui".

const newProjects = projects.map(p =>
  p.value === 'jquery-ui'
    ? { ...p, desc: 'new description' }
    : p
);
kintaro
fuente
1
De hecho, la mejor solución real! Gracias.
Frederiko Cesar
1
@FrederikoCesar no en todos los casos, iterar sobre cada objeto cuesta más que cortar la matriz e inyectar el nuevo objeto usando el operador de propagación
Maged Mohamed
¿Qué pasa si desea cambiar el valor sobre la marcha? Sin crear otra var? La mejor manera es el método de índice: const targetIndex = summerFruits.findIndex (f => f.id === 3);
Thanasis
37

Puede usar $ .each () para iterar sobre la matriz y ubicar el objeto que le interesa:

$.each(projects, function() {
    if (this.value == "jquery-ui") {
        this.desc = "Your new description";
    }
});
Frédéric Hamidi
fuente
36

Usar map es la mejor solución sin usar bibliotecas adicionales. (Usando 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
);
Ankit Kumar Rajpoot
fuente
19

Se puede lograr fácilmente con la biblioteca de subrayado / lodash:

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

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

usuario2765479
fuente
¿Qué sucede si la función de búsqueda no encuentra 'jquery-ui'?
Mika
La propiedad 'find' no existe en el tipo 'LoDashExplicitArrayWrapper'
AndrewBenjamin el
El resultado de tales secuencias debe desenvolverse con el valor _ #. lodash.com/docs/4.17.4#chain .value()
p0k8_
17

puedes usar .find así en tu ejemplo

   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'
abe kur
fuente
¡Asombroso! +1
Mike Musni
12

necesita saber el índice del objeto que está cambiando. entonces es bastante simple

projects[1].desc= "new string";
Elasticrash
fuente
8

Creo que así es mejor

const index = projects.findIndex(project => project.value==='jquery-ui');
projects[index].desc = "updated desc";
tsadkan yitbarek
fuente
en tu findIndexeres la asignación de un valor en vez de comparar
avalanche1
6

dados los siguientes datos, queremos reemplazar las bayas en la summerFruitslista con sandía .

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

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

Dos formas de hacer esto.

Primer enfoque:

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

Segundo enfoque: usar map, y spread:

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

summerFruitsCopy La lista ahora devolverá una matriz con un objeto actualizado.

meol
fuente
El primer método es el mejor. No es necesario pasar a otra var y luego volver. Sobre la marcha método. He votado tu solución.
Thanasis
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)];

Leo Lanese
fuente
esto ...antes de que los proyectos sean necesarios?
lazzy_ms
@lazzy_ms ...se conoce como el operador de propagación. google it :)
rmcsharry
4

Esta es otra respuesta que involucra find. Esto se basa en el hecho de que find:

  • itera a través de cada objeto en la matriz HASTA que se encuentre una coincidencia
  • cada objeto se le proporciona y es MODIFICABLE

Aquí está el fragmento crítico de Javascript:

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

Aquí hay una versión alternativa del mismo Javascript:

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

Aquí hay una versión aún más corta (y algo más malvada):

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

Aquí hay una versión de trabajo completa:

  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"
            }
        ];

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

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

Stephen Quan
fuente
3

Puedes usar la función de mapa -

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

this.setState({ answers: answers })
gandharv garg
fuente
0

Prueba este código. utiliza la función jQuery grep

array = $.grep(array, function (a) {
    if (a.Id == id) {
        a.Value= newValue;
    }
    return a;
});
Mohammed Kamran Azam
fuente
0

También podemos usar la función de mapa de Array para modificar el objeto de una matriz usando Javascript.

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

changeDesc('jquery', 'new description')
Mahima Agrawal
fuente
esto devolverá [nulo, objeto con el valor actualizado, nulo]
Fernando Caride
0

Encuentra el índice primero:

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++;
        }
      }

Luego:

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

Luego haz lo que quieras con este índice, como:

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

Nota: no use for, ya que for verificará todos los documentos de la matriz, use mientras que con un tope, por lo que se detendrá una vez que se encuentre, por lo tanto, un código más rápido.


fuente
0

Aquí estoy usando angular js. En javascript puedes usar for loop para encontrar.

    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");
    }
Hari Lakkakula
fuente
-1

para actualizar varios elementos con las coincidencias use:

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

Esta es mi respuesta al problema. Mi versión de subrayado fue 1.7, por lo tanto, no pude usar .findIndex.

Así que obtuve manualmente el índice del artículo y lo reemplacé. Aquí está el código para el mismo.

 var students = [ 
{id:1,fName:"Ajay", lName:"Singh", age:20, sex:"M" },
{id:2,fName:"Raj", lName:"Sharma", age:21, sex:"M" },
{id:3,fName:"Amar", lName:"Verma", age:22, sex:"M" },
{id:4,fName:"Shiv", lName:"Singh", age:22, sex:"M" }
               ]

El siguiente método reemplazará al alumno id:4con más atributos en el objeto

function updateStudent(id) {
 var indexOfRequiredStudent = -1;
    _.each(students,function(student,index) {                    
      if(student.id === id) {                        
           indexOfRequiredStudent = index; return;      
      }});
 students[indexOfRequiredStudent] = _.extend(students[indexOfRequiredStudent],{class:"First Year",branch:"CSE"});           

}

Con el subrayado 1.8 se simplificará ya que tenemos métodos _.findIndexOf.

Sanjay Bharwani
fuente
-1

Permitir que desee actualizar el valor de array[2] = "data"

    for(i=0;i<array.length;i++){
      if(i == 2){
         array[i] = "data";
        }
    }
Vinod kumar
fuente
¿Es esta una respuesta o una pregunta?
tabdiukov
2
Actualizó con éxito el segundo elemento de esa matriz de la manera más complicada posible.
BlueWater86
-1
let thismoth = moment(new Date()).format('MMMM');
months.sort(function (x, y) { return x == thismoth ? -1 : y == thismoth ? 1 : 0; });
Navnath jagdale
fuente
1
Proporcione una descripción a su respuesta.
Lajos Arpad