Як змінити значення об'єкта, який знаходиться всередині масиву, використовуючи JavaScript або jQuery?


206

Код нижче походить від автоматичного заповнення інтерфейсу 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"
    }
];

Наприклад, я хочу змінити значення desc jquery-ui . Як я можу це зробити?

Крім того, чи є більш швидкий спосіб отримати дані? Я маю на увазі дати об’єкту ім'я для отримання його даних, як і об'єкт у масиві? Так це було б щось на кшталтjquery-ui.jquery-ui.desc = ....


Вам доведеться перетворити масив в об’єкт Javascript, щоб використовувати синтаксис projects["jquery-ui"].desc. Чи варто це докласти зусиль лише для того, щоб отримати симпатичніший синтаксис?
Фредерік Хаміді

Я оновив своє рішення з вашим останнім запитанням. І ви можете використовувати позначення "projects.jquery-ui.desc".
Астон

Відповіді:


135

Ви повинні шукати в масиві на зразок:

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

і використовувати його як

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

ОНОВЛЕННЯ:

Щоб отримати його швидше:

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

projects.jqueryUi.desc = 'new string';

(Відповідно до коментаря Фредерика, ви не повинні використовувати дефіс в об'єктному ключі, або ви повинні використовувати "jquery-ui" та проекти ["jquery-ui"].)


Чи існує набагато швидший спосіб отримати дані? Я маю на увазі дати об’єкту ім'я, щоб отримати його дані. Так само, як об’єкт всередині масиву. Отже, чи можу я використовувати його таким чином: jquery-ui.jquery-ui.desc = ....
qinHaiXiang

2
ваше оновлення не працюватиме через дефіс -у назві об'єкта. Вам би довелося писати "jquery-ui": {}і projects["jquery-ui"].descвідповідно.
Фредерік Хаміді

Дякую, я цього не знав.
Астон

подивіться на відповідь
абе кур

236

Це досить просто

  • Знайдіть індекс об’єкта за допомогою findIndex методу.
  • Зберігайте індекс у змінній.
  • Зробіть просте оновлення, як це: 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
Будь-яка причина для подвійних ()по findIndexметоду?
Терхос

3
це буде вимкнути myArray.
Bimal Grg

1
Так, але якщо ви не хочете мутувати. [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], myArray.slice(objIndex + 1))]
Умаїр Ахмед

1
@UmairAhmed Чи не повинен бути вказаний вище код [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], ...myArray.slice(objIndex + 1))]? Я думаю, що ур пропускає другі еліпси.
Крейг

1
люби, як це чисто!
tdelam

58

ES6 спосіб, без мутації оригінальних даних.

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

56

Найкраще рішення, завдяки ES6.

Це повертає новий масив із заміненим описом для об'єкта, який містить значення, рівне "jquery-ui".

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

1
Справді, найкраще фактичне рішення! Дякую.
Фредеріко Сезар

1
@FrederikoCesar не у всіх випадках ітерація над кожним об'єктом коштує більше, ніж зрізання масиву та введення нового об’єкта за допомогою оператора розширення
Maged Mohamed

що робити, якщо ви хочете змінити значення на льоту? Без створення іншого вару? Найкращий спосіб - метод індексу: const targetIndex = summerFruits.findIndex (f => f.id === 3);
Танасіс


36

Використання карти - найкраще рішення без використання зайвих бібліотек (за допомогою 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

Це легко досягти за допомогою бібліотеки підкреслення / подачі:

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

Документи:
https://lodash.com/docs#find
https://lodash.com/docs#merge


Що робити, якщо функцію знаходження "jquery-ui" не знайдено?
Міка

Властивості 'find' не існує в типі 'LoDashExplicitArrayWrapper'
AndrewBenjamin

Результат таких послідовностей повинен бути розкручений зі значенням _ #. lodash.com/docs/4.17.4#chain .value()
p0k8_

17

ви можете використовувати .find так у своєму прикладі

   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'

Дивовижний! +1
Майк Мусні

12

вам потрібно знати індекс об'єкта, який ви змінюєте. то його досить просто

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

8

Я думаю, що цей спосіб краще

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

в вашому findIndexви привласнюєте значення замість порівняння
avalanche1

7

з огляду на наступні дані, ми хочемо замінити ягоди в summerFruitsсписку кавуном .

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

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

Два способи зробити це можна.

Перший підхід:

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

Другий підхід: використання mapта spread:

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

summerFruitsCopy Тепер список поверне масив з оновленим об'єктом.


Перший спосіб найкращий. Не потрібно переходити на інший вар, а потім назад. На льоту методом. Я голосував за ваше рішення.
Танасіс

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


це ...перед тим, як необхідні проекти?
lazzy_ms

@lazzy_ms the ...відомий як оператор розповсюдження. google it :)
rmcsharry

4

Це ще одна відповідь, що стосується find. Це спирається на той факт, що find:

  • повторюється через кожен об’єкт у масиві ДО ТОЛЬКОГО не знайдено відповідності
  • кожен об’єкт надається вам і МОДИФІКАТИВНИЙ

Ось критичний фрагмент JavaScript:

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

Ось альтернативна версія того ж Javascript:

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

Ось ще коротша (і дещо зліша версія):

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

Ось повна робоча версія:

  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

Ви можете використовувати функцію карти -

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

Ми також можемо використовувати функцію карти Array для зміни об’єкта масиву за допомогою Javascript.

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

changeDesc('jquery', 'new description')

це поверне [null, об’єкт із оновленим значенням, null]
Fernando Caride,

0

Знайдіть спочатку індекс:

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

Тоді:

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

Потім робіть те, що ви хочете, за допомогою цього індексу, наприклад:

$ range [returnindex] .someKey = "деякийValue";

Примітка: будь ласка, не використовуйте для, оскільки for перевірятиме всі документи масиву, використовуйте при цьому пробку, тому він зупиняється, як тільки буде знайдений, тим самим швидший код.


0

Тут я використовую кутовий js. У javascript ви можете використовувати loop для пошуку.

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

0

спробуйте скористатися forEach(item,index)помічником

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 search_to_change = 'jquery'

projects.forEach((item,index)=>{
   if(item.value == search_to_change )
      projects[index].desc = 'your description ' 
})

-1

для оновлення кількох елементів із використанням відповідностей:

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

-1

Це моя відповідь на проблему. Моя версія підкреслення становила 1,7, тому я не міг користуватися .findIndex.

Тому я вручну дістав індекс елемента і замінив його. Ось код для того ж.

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

Нижче метод замінить студента id:4на більше атрибутів в об'єкті

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

}

З підкресленням 1.8 це буде спрощено, як у нас є методи _.findIndexOf.


-1

Дозвольте оновити значення array[2] = "data"

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

Це відповідь чи питання?
табдюков

2
Ви успішно оновили другий елемент у цьому масиві найскладнішим можливим способом.
BlueWater86

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.