Jak zmienić wartość obiektu znajdującego się w tablicy za pomocą JavaScript lub jQuery?

204

Poniższy kod pochodzi z autouzupełniania interfejsu użytkownika 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"
    }
];

Na przykład chcę zmienić wartość desc jquery-ui . Jak mogę to zrobić?

Ponadto, czy istnieje szybszy sposób na uzyskanie danych? Mam na myśli nadać obiektowi nazwę, by pobierał jego dane, tak jak obiekt w tablicy? To by było coś w rodzajujquery-ui.jquery-ui.desc = ....

qinHaiXiang
źródło
Aby użyć składni, trzeba przekształcić tablicę w obiekt JavaScript projects["jquery-ui"].desc. Czy to byłoby warte wysiłku, aby uzyskać lepszą składnię?
Frédéric Hamidi
Zaktualizowałem swoje rozwiązanie o twoje ostatnie pytanie. I możesz użyć notacji „projects.jquery-ui.desc”.
Aston

Odpowiedzi:

135

Musisz wyszukać w tablicy, np .:

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

i używaj go jak

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

AKTUALIZACJA:

Aby uzyskać to szybciej:

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

projects.jqueryUi.desc = 'new string';

(Zgodnie z komentarzem Frédérica nie należy używać łącznika w kluczu obiektu lub należy użyć notacji „jquery-ui” i notacji [jquery-ui]).)

Aston
źródło
Czy istnieje znacznie szybszy sposób na uzyskanie danych? Mam na myśli nadanie temu obiektowi nazwy w celu pobrania jego danych. Podobnie jak obiekt wewnątrz tablicy, więc czy mogę użyć w ten sposób: jquery-ui.jquery-ui.desc = ....
qinHaiXiang
2
Twoja aktualizacja nie będzie działać z powodu łącznika -w nazwie obiektu. Trzeba by napisać "jquery-ui": {}i projects["jquery-ui"].descodpowiednio.
Frédéric Hamidi
Dziękuję, nie wiedziałem o tym.
Aston
spójrz na odpowiedź abe kur, to prawda, ta i inne są długie
stackdave
233

To jest dość proste

  • Znajdź indeks obiektu za pomocą findIndexmetody.
  • Przechowuj indeks w zmiennej.
  • Wykonaj prostą aktualizację: 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
źródło
2
Każdy powód do podwójnej ()na findIndexmetody?
Terkhos
3
zmutuje myArray.
Bimal Grg
1
Tak, ale jeśli nie chcesz mutować. [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], myArray.slice(objIndex + 1))]
Umair Ahmed
1
@UmairAhmed Czy powyższy kod nie powinien być [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], ...myArray.slice(objIndex + 1))]? Myślę, że brakuje ci drugiej elipsy.
Craig,
1
uwielbiam, jak czyste jest to!
tdelam
58

Sposób ES6 , bez mutowania oryginalnych danych.

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
źródło
55

Najlepsze rozwiązanie dzięki ES6.

Zwraca nową tablicę z zastąpionym opisem dla obiektu, który zawiera wartość równą „jquery-ui”.

const newProjects = projects.map(p =>
  p.value === 'jquery-ui'
    ? { ...p, desc: 'new description' }
    : p
);
kintaro
źródło
1
Rzeczywiście najlepsze rzeczywiste rozwiązanie! Dzięki.
Frederiko Cesar
1
@FrederikoCesar nie we wszystkich przypadkach, iteracja nad każdym obiektem kosztuje więcej niż przecięcie tablicy i wstrzyknięcie nowego obiektu za pomocą operatora rozprzestrzeniania
Maged Mohamed
co jeśli chcesz zmienić wartość w locie? Bez tworzenia kolejnego var? Najlepszym sposobem jest metoda indeksowa: const targetIndex = summerFruits.findIndex (f => f.id === 3);
Thanasis
37

Możesz użyć $ .each () do iteracji po tablicy i zlokalizowania interesującego Cię obiektu:

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

Korzystanie z mapy jest najlepszym rozwiązaniem bez użycia dodatkowych bibliotek. (Przy użyciu 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
źródło
19

Można to łatwo osiągnąć za pomocą biblioteki podkreślenia / lodash:

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

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

użytkownik2765479
źródło
Co jeśli „jquery-ui” nie zostanie znalezione przez funkcję find?
Mika
Właściwość „znajdź” nie istnieje dla typu „LoDashExplicitArrayWrapper”
AndrewBenjamin,
Wynik takich sekwencji należy rozpakować wartością _ #. lodash.com/docs/4.17.4#chain .value()
p0k8_
17

możesz użyć .find w swoim przykładzie

   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
źródło
Niesamowity! +1
Mike Musni,
12

musisz znać indeks zmienianego obiektu. to jest całkiem proste

projects[1].desc= "new string";
elastyczna wysypka
źródło
8

Myślę, że ten sposób jest lepszy

const index = projects.findIndex(project => project.value==='jquery-ui');
projects[index].desc = "updated desc";
tsadkan yitbarek
źródło
w swoim findIndexprzypisujesz wartość zamiast porównywać
lawina 1
6

biorąc pod uwagę następujące dane, chcemy zastąpić jagody na summerFruitsliście arbuzem .

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

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

Możesz to zrobić na dwa sposoby.

Pierwsze podejście:

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

Drugie podejście: użycie mapi spread:

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

summerFruitsCopy lista zwróci teraz tablicę ze zaktualizowanym obiektem.

meol
źródło
Pierwsza metoda jest najlepsza. Nie ma potrzeby przechodzenia do innego var, a następnie z powrotem. Metoda w locie. Głosowałem za twoim rozwiązaniem.
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
źródło
to ...zanim projekty są konieczne?
lazzy_ms
@lazzy_ms the ...jest znany jako operator rozprzestrzeniania. google it :)
rmcsharry
4

To kolejna odpowiedź find. Opiera się to na tym, że find:

  • iteruje przez każdy obiekt w tablicy, dopóki nie zostanie znalezione dopasowanie
  • każdy obiekt jest dostarczany i jest MODYFIKOWANY

Oto krytyczny fragment kodu JavaScript:

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

Oto alternatywna wersja tego samego Javascript:

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

Oto jeszcze krótsza (i nieco bardziej zła wersja):

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

Oto pełna działająca wersja:

  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
źródło
3

Możesz użyć funkcji mapy -

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
źródło
0

Wypróbuj ten kod. używa funkcji jQuery grep

array = $.grep(array, function (a) {
    if (a.Id == id) {
        a.Value= newValue;
    }
    return a;
});
Mohammed Kamran Azam
źródło
0

Możemy również użyć funkcji mapy Array do modyfikacji obiektu tablicy za pomocą Javascript.

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

changeDesc('jquery', 'new description')
Mahima Agrawal
źródło
to zwróci [null, obiekt o zaktualizowanej wartości, null]
Fernando Caride
0

Najpierw znajdź indeks:

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

Następnie:

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

Następnie rób, co chcesz z tym indeksem, na przykład:

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

Uwaga: nie używaj dla, ponieważ for sprawdzi wszystkie dokumenty tablicy, użyj podczas gdy z ogranicznikiem, więc zatrzyma się po znalezieniu, a tym samym szybszym kodzie.


źródło
0

Tutaj używam kątowego js. W javascript możesz użyć pętli do znalezienia.

    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
źródło
-1

aby zaktualizować wiele przedmiotów za pomocą dopasowań użyj:

_.chain(projects).map(item => {
      item.desc = item.value === "jquery-ui" ? "new desc" : item.desc;
      return item;
    })
abhisekpaul
źródło
-1

To moja odpowiedź na problem. Moja wersja podkreślenia to 1.7, więc nie mogłem jej używać.findIndex .

Więc ręcznie zdobyłem indeks przedmiotu i go wymieniłem. Oto kod tego samego.

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

Poniższa metoda zastąpi ucznia id:4większą liczbą atrybutów w obiekcie

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

}

Z podkreśleniem 1.8 zostanie uproszczone, ponieważ mamy metody _.findIndexOf.

Sanjay Bharwani
źródło
-1

Pozwól, że chcesz zaktualizować wartość array[2] = "data"

    for(i=0;i<array.length;i++){
      if(i == 2){
         array[i] = "data";
        }
    }
Vinod Kumar
źródło
Czy to odpowiedź czy pytanie?
tabdiukov
2
Udało ci się zaktualizować 2. pozycję w tej tablicy w najbardziej skomplikowany możliwy sposób.
BlueWater86
-1
let thismoth = moment(new Date()).format('MMMM');
months.sort(function (x, y) { return x == thismoth ? -1 : y == thismoth ? 1 : 0; });
Navnath jagdale
źródło
1
Podaj opis swojej odpowiedzi.
Lajos Arpad