質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

Lodash

Lodashは、JavaScriptのユーティリティライブラリ。Underscoreの派生ライブラリで、配列・オブジェクトの操作に便利です。また、コードの可読性も高めることができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

5回答

5148閲覧

連想配列が入った配列の、要素のひとつの値を上書きしたい

serona

総合スコア25

ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

Lodash

Lodashは、JavaScriptのユーティリティライブラリ。Underscoreの派生ライブラリで、配列・オブジェクトの操作に便利です。また、コードの可読性も高めることができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/01/30 03:40

編集2018/01/30 04:26

ES6についての質問です。
現在、lodashというライブラリを使用しています。

例えば、以下のような配列があったとして

const users = [ { id:1, name:'田中太郎', point:30, profile:'こんにちは', }, { id:2, name:'青井花子', point:50, profile:'おはよう', }, { id:3, name:'石野次郎', point:45, profile:'おやすみ', }, ]

この、「id:1」の要素の「point」を「40」に、「profile」を「'ハロー'」に変更し、
さらに「name」の昇順に並び替えをしたい、という場合
どのようにすれば簡潔に処理できるでしょうか?

現在は以下のような形で書いていますが、冗長な気がします…

const userChange (id, point, profile) => { const oldItem = _.find(users, ['id', id]); const newItem = _.assign({}, oldItem, { point, profile }); return _.sortBy(_.concat(_.without(users, oldItem), newItem), 'name'); } // userChange(1, 40, 'ハロー');

翻訳に頼りつつ、何とかlodashのドキュメントを読みながら、自分なりに調べていますが
なかなか良い方法が見つかりません。
どなたかアドバイスや案内してもらえると嬉しいです><
もし、既に似たような質問があったり、これに該当する解決策の記事があったりしたらすみません…!

追記・・・
修正依頼ありがとうございます…!
非破壊的な方法で変更したいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2018/01/30 03:47 編集

users[0]やusers自身は破壊的に変更して問題ないですか?
guest

回答5

0

ベストアンサー

JavaScript標準のAPIを使えばこんな感じ.

JavaScript

1//当該要素の抽出 2const user = users.find(user => user.id == 1); 3user.point = 40; 4user.profile = "ハロー"; 5//ソート(破壊的) 6users.sort((a, b) => a.name < b.name ? -1 : a.name == b.name ? 0 : 1); 7console.log(users); 8

ソートを非破壊的に行うなら, 配列の(シャロー)コピーを作ってからソートすればよい.

JavaScript

1//ソート(配列をシャローコピーした後ソート) 2const sorted = users.concat().sort((a, b) => a.name < b.name ? -1 : a.name == b.name ? 0 : 1);

投稿2018/01/30 03:53

編集2018/01/30 05:08
defghi1977

総合スコア4756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

serona

2018/01/30 04:33

回答ありがとうございます! こういうやり方があるんですね…!参考にさせて頂きますー!!
guest

0

ES6 を使用していいいのなら、ここまで短く書けます(Polyfill で対応可能な範疇ですね)。

JavaScript

1var user = Object.assign(users.find(user => user.id === 1), {point: 40, profile: 'ハロー'}); 2console.log(JSON.stringify(user)); // {"id":1,"name":"田中太郎","point":40,"profile":"ハロー"}

Re: serona さん

投稿2018/01/30 04:41

think49

総合スコア18189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

serona

2018/01/30 04:46

回答ありがとうございます!参考にさせて頂きます!
guest

0

あんまり省略できてなさそうですが、とりあえず書いて見ました。
Arrayの機能で済ませるとこうなりますかね。
参考になれば
https://jsfiddle.net/oligin/7t5kv7gd/10/

投稿2018/01/30 04:13

編集2018/01/30 04:14
oligin

総合スコア138

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

serona

2018/01/30 04:32

回答ありがとうございます! こういう書き方があるんですね…!この方が変更が分かりやすいですね 参考になりました!感謝です(*´∀`*)
guest

0

lodashのメリットはchainでつなげての遅延評価(v3以降)による最適化処理だと思います。
今回はfindで絞っているし、sortはその特性上、流れが切られるので最適化の対象とならないですが^^
lodashを使うなら、chain(遅延評価)を使うことをお勧めします。

js

1var userChange = (id, point, profile)=> { 2 _.chain( users ) 3 .find( {id:id} ) 4 .assign( { point: point, profile: profile } ) 5 .commit(); 6 return _.sortBy( users, 'name' ); 7 } 8

lodashの遅延評価についての参考ページ
http://yohshiy.blog.fc2.com/blog-entry-308.html

あとlodashはわりと破壊的なのでassignを使わなくても
findで取り出したオブジェクトをそのまま触ると上書きされます。
ただこれなら標準APIでいいかな~

js

1var userChange = (id, point, profile)=> { 2 const user = _.find( users, {id:id} ); 3 user.point = point; 4 user.profile = profile; 5 return _.sortBy( users, 'name' ); 6 } 7

追記です。
「非破壊的な方法で変更したい」というのを見逃していたので修正版も。

js

1const userChange = (id, point, profile)=> { 2 return _.chain( users ) 3 .cloneDeep() //複製 4 .tap( users => { 5 //強引に中間操作・・・ 6 _.chain(users).find( {id:id} ).assign( { point: point, profile: profile } ).commit(); 7 }) 8 .sortBy('name') 9 .value(); 10 }

投稿2018/01/30 05:00

編集2018/01/30 09:22
so87

総合スコア764

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

serona

2018/01/30 08:45

回答ありがとうございます! なるほど!そうやって使うんですね…(@_@) 勉強不足でお恥ずかしい限りです…!とても参考になりました!
guest

0

lodashはわかりませんが

Javascript

1var users = [ 2 { 3 id:1, 4 name:'田中太郎', 5 point:30, 6 profile:'こんにちは', 7 }, 8 { 9 id:2, 10 name:'青井花子', 11 point:50, 12 profile:'おはよう', 13 }, 14 { 15 id:3, 16 name:'石野次郎', 17 point:45, 18 profile:'おやすみ', 19 }, 20]; 21 22//プロパティ変更 23with(users.filter(function(x){ 24 return x.id==1; 25})[0]){point=40;profile='ハロー'}; 26 27//nameでソート 28users.sort(function(x,y){ 29 return x.name == y.name?0:(x.name<y.name?1:-1); 30}); 31 32console.log(users); 33

各要素のidがユニークである前提です。

投稿2018/01/30 04:16

yambejp

総合スコア116468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

serona

2018/01/30 04:28

回答ありがとうございます! 各要素のidはユニークな値です。 参考にさせて頂きます!(>人<)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問