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

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

Aston
fonte
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])

Umair Ahmed
fonte
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);
Bimal Grg
fonte
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
);
kintaro
fonte
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";
    }
});
Frédéric Hamidi
fonte
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
);
Ankit Kumar Rajpoot
fonte
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

user2765479
fonte
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'
abe kur
fonte
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";
elasticrash
fonte
8

Acho que assim é melhor

const index = projects.findIndex(project => project.value==='jquery-ui');
projects[index].desc = "updated desc";
tsadkan yitbarek
fonte
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.

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

Leo Lanese
fonte
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 ) );

Stephen Quan
fonte
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 })
gandharv garg
fonte
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;
});
Mohammed Kamran Azam
fonte
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')
Mahima Agrawal
fonte
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.


fonte
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");
    }
Hari Lakkakula
fonte
-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;
    })
abhisekpaul
fonte
-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.

Sanjay Bharwani
fonte
-1

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

    for(i=0;i<array.length;i++){
      if(i == 2){
         array[i] = "data";
        }
    }
Vinod kumar
fonte
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; });
Navnath jagdale
fonte
1
Forneça uma descrição para sua resposta.
Lajos Arpad