Como alterar o valor do objeto que está dentro de uma matriz usando JavaScript ou jQuery?


200

O código abaixo vem do preenchimento automático da interface do usuário do jQuery:

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 exemplo, eu quero alterar o valor desc de jquery-ui . Como eu posso fazer isso?

Além disso, existe uma maneira mais rápida de obter os dados? Quero dizer, dar ao objeto um nome para buscar seus dados, assim como o objeto dentro de uma matriz? Então seria algo comojquery-ui.jquery-ui.desc = ....


Você precisaria transformar a matriz em um objeto Javascript para usar a sintaxe projects["jquery-ui"].desc. Isso valeria a pena o esforço apenas para obter uma sintaxe melhor?
Frédéric Hamidi

Atualizei minha solução com sua pergunta mais recente. E você pode usar a notação "projects.jquery-ui.desc".
Aston

Respostas:


135

Você deve procurar na 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!
     }
   }
}

e use-o como

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

ATUALIZAR:

Para obter mais rápido:

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

projects.jqueryUi.desc = 'new string';

(De acordo com o comentário de Frédéric, você não deve usar hífen na chave do objeto ou usar "jquery-ui" e notação de projetos ["jquery-ui"].)


Existe uma maneira muito mais rápida de obter os dados? Quero dizer dar ao objeto um nome para buscar sua data.Just como o objeto dentro array.So, posso usado dessa forma: jquery-ui.jquery-ui.desc = ....
qinHaiXiang

2
sua atualização não funcionará devido ao hífen -no nome do objeto. Você teria que escrever "jquery-ui": {}e, projects["jquery-ui"].descrespectivamente.
Frédéric Hamidi

Obrigado, eu não sabia disso.
Aston

olhar para a resposta do abe do Kur, que é o direito, isso e anothers são longos
stackdave

230

É bem simples

  • Encontre o índice do objeto usando o findIndexmétodo
  • Armazene o índice na variável
  • Faça uma atualização simples 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
Alguma razão para o duplo ()no findIndexmétodo?
Terkhos

3
isso mudará o myArray.
Bimal Grg

1
Sim, mas se você não quiser sofrer mutações. [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], myArray.slice(objIndex + 1))]
Umair Ahmed

1
@UmairAhmed O código acima não deve ser [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], ...myArray.slice(objIndex + 1))]? Acho que você está perdendo as segundas elipses.
Craig

1
amo como isso é limpo!
tdelam 10/05/19

56

ES6 , sem alterar os dados originais.

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

A melhor solução, graças ao ES6.

Isso retorna uma nova matriz com uma descrição substituída para o objeto que contém um valor igual a "jquery-ui".

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

1
Na verdade, a melhor solução real! Obrigado.
Frederiko Cesar

1
@FrederikoCesar nem sempre, iterar sobre cada objeto custa mais do que fatiar a matriz e injetar o novo objeto usando o operador spread
Maged Mohamed

e se você quiser alterar o valor rapidamente? Sem criar outro var? A melhor maneira é o método de índice: const targetIndex = summerFruits.findIndex (f => f.id === 3);
Thanasis

37

Você pode usar $ .each () para percorrer a matriz e localizar o objeto em que está interessado:

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

36

Usar o mapa é a melhor solução sem o uso de bibliotecas extras. (Usando o 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

É facilmente possível com a biblioteca de sublinhado / lodash:

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

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


E se 'jquery-ui' não for encontrado pela função find?
Mika

Propriedade 'encontrar' não existe no tipo 'LoDashExplicitArrayWrapper'
AndrewBenjamin

O resultado dessas seqüências deve ser desembrulhado com o valor _ #. lodash.com/docs/4.17.4#chain .value()
p0k8_

17

você pode usar .find então no seu exemplo

   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'

Surpreendente! 1
Mike Musni 11/09/19

12

você precisa conhecer o índice do objeto que está mudando. então é bem simples

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

8

Acho que assim é melhor

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

em sua findIndexvocê está atribuindo um valor em vez de comparar
avalanche1

6

dados os seguintes dados, queremos substituir as frutas da summerFruitslista por melancia .

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

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

Duas maneiras de fazer isso.

Primeira abordagem:

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

Segunda abordagem: usando mape spread:

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

summerFruitsCopy Agora a lista retornará uma matriz com o objeto atualizado.


O primeiro método é o melhor. Não há necessidade de mudar para outra var e depois voltar. Método instantâneo. Eu votei na sua solução.
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)];


isso ...antes que os projetos sejam necessários?
Lazzy_ms 29/08/19

@lazzy_ms ...é conhecido como o operador de propagação. Google it :)
rmcsharry 15/09/19

4

Esta é outra resposta envolvente find. Isso se baseia no fato de que find:

  • itera através de cada objeto na matriz até que uma correspondência seja encontrada
  • cada objeto é fornecido a você e é MODIFICÁVEL

Aqui está o trecho crítico do Javascript:

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

Aqui está uma versão alternativa do mesmo Javascript:

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

Aqui está uma versão ainda mais curta (e um pouco mais maligna):

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

Aqui está uma versão de trabalho 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

Você pode usar a função 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

Experimente este código. ele usa a função grep do jQuery

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

0

Também podemos usar a função de mapa da matriz para modificar o objeto de uma matriz usando Javascript.

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

changeDesc('jquery', 'new description')

isso retornará [nulo, objeto com o valor atualizado, nulo] #
Fernando Caride

0

Encontre o índice primeiro:

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

Então:

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

Em seguida, faça o que você deseja com este índice, como:

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

Nota: por favor, não use for, pois para irá verificar todos os documentos da matriz, use enquanto estiver com uma rolha, para que pare assim que for encontrado, portanto, um código mais rápido.


0

Aqui eu estou usando js angulares. Em javascript, você pode usar o loop for 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 atualizar vários itens com as correspondências, use:

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

-1

Esta é a minha resposta ao problema. Minha versão de sublinhado era 1.7, portanto, eu não poderia usar .findIndex.

Então, eu peguei manualmente o índice do item e o substituí. Aqui está o código para o mesmo.

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

O método abaixo substituirá o aluno id:4por mais atributos no 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"});           

}

Com o sublinhado 1.8, será simplificado, pois temos métodos _.findIndexOf.


-1

Você deseja atualizar o valor de array[2] = "data"

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

Isso é uma resposta ou uma pergunta?
tabdiukov 13/01

2
Você atualizou com êxito o segundo item dessa matriz da maneira mais complicada possível.
BlueWater86 13/01

-1
let thismoth = moment(new Date()).format('MMMM');
months.sort(function (x, y) { return x == thismoth ? -1 : y == thismoth ? 1 : 0; });

1
Forneça uma descrição para sua resposta.
Lajos Arpad
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.