質問内容
ユーザーの「ID」「氏名」が入った二次元配列に対して、IDが重複していたら重複を削除する(後ろに入っているレコードを残す)というプログラムがあるのですが、
表記方法が見慣れない書き方になっており、手を加えられない状態です(例によって製作者は不在)。
この表記でどういう動作をしているのか、教えていただけないでしょうか。
また、同じ様な表記方法をしているリファレンスや参考ページがあればリンクを貼っていただけると大変助かります。
該当のソースコード
javascript
1 2//ID,名前 3var arrUser =[ 4 ['001', '小林'], 5 ['002', '山田'], 6 ['003', '中村'], 7 ['001', '大林'] 8]; 9 10//IDが重複しているレコードを削除 11var arrNewUser = []; 12for (var i = 0; i < arrUser.length; i++) { 13 arrNewUser[arrUser[i][0]] = arrUser[i]; // この表記法がわからない 14} 15console.table(arrNewUser); //山田,中村,大林
恐らくIDが同じであれば上書きをしているのだと思いますが、こういう書き方はアリなんでしょうか。(当然アリだから動いているんですが・・・)
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
利用用途
恐らくIDが同じであれば上書きをしているのだと思いますが、こういう書き方はアリなんでしょうか。(当然アリだから動いているんですが・・・)
上書きの是非は「仕様が用途にマッチするか」に尽きるので、コードだけでは判断できません。
問題点
現行仕様を強襲すると、既定のプロパティと衝突してしまう問題があります。
JavaScript
1function original (arrUser) { 2 var arrNewUser = []; 3 4 for (var i = 0; i < arrUser.length; i++) { 5 arrNewUser[arrUser[i][0]] = arrUser[i]; 6 } 7 8 return arrNewUser; 9} 10 11console.table(original([['001', '小林'],['002', '山田'],['003', '中村'],['001', '大林']])); 12console.dir(original([['__proto__','伊藤']])); 13console.dir(original([['length','佐々木']])); // RangeError: Invalid array length
配列に数値以外のプロパティで代入する事は本来の用途ではなく、プロパティ拡張には既定プロパティと衝突する危険性が常にあります。
整理すれば、次のオブジェクトまで落とし込めますが、__proto__
と衝突する問題は残っています。
JavaScript
1{"001":"大林","002":"山田","003":"中村"}
Map
この問題を解決する最も簡単な方法はMapを使用する事です。
JavaScript
1function fixed (users) { 2 return new Map(users); 3} 4 5var userMap = fixed([['001', '小林'],['002', '山田'],['003', '中村'],['001', '大林'],['__proto__','伊藤'],['length','佐々木']]); 6 7console.log(JSON.stringify([...userMap.entries()])); // [["001","大林"],["002","山田"],["003","中村"],["__proto__","伊藤"],["length","佐々木"]]
参考情報。
Re: kobacj さん
投稿2018/04/26 11:53
編集2018/04/26 13:42総合スコア18156
0
こういう書き方はアリなんでしょうか。
以下で説明する問題があるため、ナシだと思います。
arrNewUser[arrUser[i][0]] = arrUser[i];
の部分はfor文の1ループ目では以下のように例えば置き換わります。
arrNewUser['001'] = ['001', '小林'];
なので、一旦、このコードをもっと簡易的なものに説明用にこうしてみます。
var arrNewUser = []; arrNewUser['001'] = ['001', '小林'];
では、この配列に対して、forEach
などの配列操作を行なったり、length
プロパティーを参照したりすると、どうなるかというと、
var arrNewUser = []; arrNewUser['001'] = ['001', '小林']; console.log(arrNewUser) // [ ] - 環境によっては空の配列が表示されることもあるようです。 console.log(arrNewUser.length); //0 - lengthは0 arrNewUser.forEach(function(value, index) { console.log('hello'); // 何も表示されない console.log(value, index); // 何も表示されない }) console.log(arrNewUser['001']) // こうした場合のみ[ '001', '小林' ]と出る
https://codepen.io/anon/pen/OZRgJO
というようにおかしな挙動になってしまうので、こういう場合はObject
かMap
を使うべきだと思います。
let arrNewUser = {}; arrNewUser['001'] = ['001', '小林']; console.log(arrNewUser); // { '001': [ '001', '小林' ] } console.log(arrNewUser['001']); // [ '001', '小林' ] Object.keys(arrNewUser).forEach(function(key) { console.log(arrNewUser[key]); // [ '001', '小林' ] });
let arrNewUser = new Map(); arrNewUser.set('001', ['001', '小林']); console.log(arrNewUser); // Map { '001' => [ '001', '小林' ] } console.log(arrNewUser.get('001')); // [ '001', '小林' ] console.log(arrNewUser.size); // 1 for (let user of arrNewUser.values()) { console.log(user); // [ '001', '小林' ] }
投稿2018/04/26 11:26
編集2018/04/27 01:16総合スコア2415
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ちゃんとやるならarrNewUserはObjectにすべきですね
javascript
1var arrNewUser = {};
javascriptの配列はデータの投入方法によって多少ゆるく処理してくれます
javascript
1var a=[]; 2a["x"]=1; 3console.log(a); 4var b=[]; 5b[2]=1; 6console.log(b);
投稿2018/04/26 11:08
総合スコア114572
0
ベストアンサー
arrNewUserとして新しい配列を作っていく中で重複は除外していきたいんですね。
arrNewUser[arrUser[i][0]] = arrUser[i];
一番目[001,小林] を考えてみましょう
arrUser[i][0] は? 001です
arrUser[i] は? [001,小林] です。
arrNewUser[ 001 ] = [001,小林]
この時点で
[ 1:[001,小林] ] ができます。
この調子で
[ 1:['001', '小林'], 2:['002', '山田'], 3:['003', '中村'] ]
ができるのですが。。。
次 [001,大林]でどうなるか
arrNewUser[001] = [001,大林]
arrNewUser の 1には一人目で [ 001,小林 ] が入っています。
ということで、結果的に1番目の小林を上書きしてしまい、
[ 1:['001', '大林'], 2:['002', '山田'], 3:['003', '中村'] ]
になるということです。
投稿2018/04/26 11:03
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/27 00:42
退会済みユーザー
2018/04/27 01:10
2018/04/27 03:04
2018/04/27 04:43
退会済みユーザー
2018/04/27 05:04 編集
2018/04/27 12:26
退会済みユーザー
2018/04/27 12:43 編集
2018/04/28 01:55
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/26 23:55
2018/04/27 03:16