Як змінити значення об'єкта, який знаходиться всередині масиву, використовуючи 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.