¿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 = ....


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"]).


¿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])


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

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

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

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

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


¿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'

¡Asombroso! +1
Mike Musni

12

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

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

8

Creo que así es mejor

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

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.


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)];


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


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

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

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')

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.


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

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

-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.


-1

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

    for(i=0;i<array.length;i++){
      if(i == 2){
         array[i] = "data";
        }
    }

¿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; });

1
Proporcione una descripción a su respuesta.
Lajos Arpad
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.