JavaScriptまたはjQueryを使用して配列内にあるオブジェクトの値を変更するにはどうすればよいですか?


200

以下のコードは、jQuery UIオートコンプリートからのものです。

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

たとえば、jquery-uiのdesc値を変更します。どうやってやるの?

さらに、データを取得するより速い方法はありますか?配列内のオブジェクトと同じように、オブジェクトにデータを取得するための名前を付けますか?だからそれは次のようなものになりますjquery-ui.jquery-ui.desc = ....


構文を使用するには、配列をJavascriptオブジェクトに変換する必要がありますprojects["jquery-ui"].desc。より良い構文を得るためだけの努力に値するでしょうか?
フレデリックハミディ2011年

私はあなたの最新の質問で私のソリューションを更新しました。また、「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」およびprojects ["jquery-ui"]表記を使用してください。)


データを取得するより速い方法はありますか?つまり、配列内のオブジェクトと同じように、オブジェクトに名前を付けます。つまり、そのように使用できます:jquery-ui.jquery-ui.desc = ....
qinHaiXiang

2
-オブジェクト名にハイフンが含まれているため、更新は機能しません。"jquery-ui": {}projects["jquery-ui"].descそれぞれ書く必要があります。
フレデリックハミディ2011年

ありがとう、知らなかった。
アストン

阿部クルの答えを見てください、それは正しいです、これと別のものは長いです
stackdave

230

とてもシンプルです

  • 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する方法?
Terkhos、2017年

3
myArrayが変更されます。
Bimal Grg 2018年

1
はい、しかし変異させたくない場合。[...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], myArray.slice(objIndex + 1))]
Umair Ahmed、2018

1
@UmairAhmed上記のコードは [...myArray.slice(0, objIndex), Object.assign({}, myArray[objIndex], ...myArray.slice(objIndex + 1))]どうですか?第二の楕円が欠けていると思います。
クレイグ、

1
これがどれだけきれいか大好きです!
tdelam

56

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

54

ES6のおかげで最高のソリューション。

これは、「jquery-ui」に等しい値を含むオブジェクトの置き換えられた説明を含む新しい配列を返します。

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

1
確かに最高の実際のソリューション!ありがとう。
Frederiko Cesar、

1
@FrederikoCesarがすべての場合に当てはまるわけではありません。各オブジェクトを反復処理すると、配列をスライスして、spread演算子を使用して新しいオブジェクトを挿入するよりもコストがかかります
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


find関数で「jquery-ui」が見つからない場合はどうなりますか?
ミカ

プロパティ 'find'がタイプ 'LoDashExplicitArrayWrapper'に存在しません
AndrewBenjamin

そのようなシーケンスの結果は、_#valueでラップ解除する必要があります。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

6

次のデータを考慮して、リストのベリーsummerFruitsスイカに置き換えます

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

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

これを行うには2つの方法があります。

最初のアプローチ:

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

2番目のアプローチ:map、およびspread

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

summerFruitsCopy listは、更新されたオブジェクトを含む配列を返します。


最初の方法が最善です。別の変数に移動してから戻す必要はありません。オンザフライ方式。私はあなたの解決策に賛成票を投じました。
タナシス

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これ...は、spreadオペレーターとして知られています。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

また、配列のマップ関数を使用して、JavaScriptを使用して配列のオブジェクトを変更することもできます。

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

changeDesc('jquery', 'new description')

これは[null、更新された値を持つオブジェクト、null]を
返し

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

次に、このインデックスを使用して、次のようにします。

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

注:forはすべての配列ドキュメントをチェックするため、使用しないでください。ストッパーを使用しながら使用すると、見つかった時点で停止するため、コードが高速になります。


0

ここでは、角度jsを使用しています。JavaScriptでは、forループを使用して検索できます。

    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

マッチで複数のアイテムを更新するには:

_.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";
        }
    }

これは答えですか、それとも質問ですか?
tabdiukov

2
可能な限り最も複雑な方法で、その配列の2番目の項目を正常に更新しました。
BlueWater86

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.