iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Modern Web

前端蛇行撞牆記系列 第 5

Day5 前端蛇行撞牆記 - 你有聽過循序式容器 / 關聯式容器嗎?

  • 分享至 

  • xImage
  •  

前言

為什麼要研究這個主題得從我寫的一個題目講起,
那個題目是要印出陣列中的質數,還有質數的索引值。
於是我就使用了 Object.entries() ,雖然很明顯它長得就是給物件用,可是我卻可以用!
(雖然也有一個陣列方法是array.entries(),但我當時就是沒有用~不過這兩個根本差超多)
它幫我印出二維陣列,裡面每一個都是index, value排成一個陣列。

const array = [3,11,50,2,0]

const array1 = Object.entries(array)

console.log(array1) 

//
[ [ '0', 3 ], [ '1', 11 ], [ '2', 50 ], [ '3', 2 ], [ '4', 0 ] ]

我故意不把他關起來,看到顏色了嗎?
index是被轉型成字串的樣子,長得就是物件的key值!

所以說把陣列的index跟value放在一起就會長得像物件了
但是陣列的index本來就不是可以看見的啊,為什麼我要硬把他做得像是物件的樣子呢?

那陣列為什麼是長這個樣子,而物件為什麼是長這個樣子呢?
他們同樣都不是Primitive 都是 Object,可是差在哪裡?


循序式容器與關聯式容器

在C++ 語言裡有定義循序式容器跟關聯式容器,將會以這兩個名詞來做介紹。
不過在這裡不會介紹到C++ 在這兩個容器中所包含的容器,
但同樣可以把定義對照到Javascript的陣列跟物件。

值放置在容器的方式會牽扯到資料結構~但不會深入講解
接下來要淺淺地談論,也是我目前可以理解的部分~

循序式容器 sequence container

  • 會以線性的方式來排列。
  • 要找尋元素會以被放在容器中的位置(position)來找尋。
    對照在Javascript中的元素就是以索引值(index)被找尋,就是index對應的value,就能找到value的值。
  • 搜尋順序會以從頭到尾的方式查找,要找index: 3 得從 index:1, index: 2, index: 3才能找到value

這樣應該很清楚在Javascript的循序式容器就是陣列(array)了!

const array = [3,11,50,2,0]

console.log(array[0]) // 3
console.log(array[1]) // 11
console.log(array[2]) // 50
console.log(array[3]) // 2
console.log(array[4]) // 0

仔細看上方的排列,index的順序完全跟陣列的順序一樣,而且是連續的。所以在陣列中的順序是非常重要的,中間不會跳過也不會多一個,

就像是身分證字號一樣,如果有兩個同名同姓的人,就會以身分證字號來區分這兩個人啊!

陣列裡面的index 跟 物件的 key 是不一樣的事情喔,不要搞混了!

關聯式容器 associative containe

  • 會以樹狀結構/ hash table 來放置key / value。
  • 分為Map、Set兩大類
  • 每一個元素都會以一個pair (key, value) 的方式出現
  • 不需要從頭到尾找一遍才能找到值,只要有key就可以找到value

雖然關聯式容器是到底以樹狀或是hash table存放的不可考,可能因為數量等其他因素影響JS選擇用什麼方式存放,所以本文不會深入討論。
但是可以有印象這些元素是沒有順序的放置元素,不像循序式容器一樣是線性的。

hash table(雜湊表)的示意圖:

圖片來源:維基百科

這些key值被放進去的位置不是規律、順序的。可是要找到value就用key來找。

obj可以用key來找到value:

const obj = {
  name : "Jade",
  age : 28 
}

console.log(obj.name)
// Jade

所谓关联式容器,类似关联式数据库,每笔数据或每个元素都有一个键值(key)和一个实值(value),即所谓的Key-Value(键-值对)。当元素被插入到关联式容器中时,容器内部结构(RB-tree/hashtable)便依照其键值大小,以某种特定规则将这个元素放置于适当位置。


很欠打的把陣列當成物件使用

來做一個比我當初更欠打的行為,把陣列當成物件使用~
看看如果硬把一個循序式容器裡面的樣子做得像是關聯式容器會怎麼樣

var my_array = new Array();

my_array["name"] = "Jade";
my_array["age"] = 28;
my_array["city"] = "Taipei";

for (i of my_array) {
   console.log(i); 
};

// 沒結果

啊~果然,他現在已經不把這個陣列當成陣列了,所以不能使用for...of

那那那不然來用物件常用的for...in好了:

for (i in my_array) {
   console.log(i); 
};

//
name
age
city

就是for...in會發生的事!把key值產出!

用用看length..

console.log(my_array.length); 
// 0

my_array.push("hey") 
console.log(my_array);
// [ 'hey', name: 'Jade', age: 28, city: 'Taipei' ]
//根本push不上去!

是0啊,等於這個陣列沒有東西?!
然後根本也push不上去..

最後來看看他到底是啥?!

console.log(typeof my_array)

// object

你應該也猜到了...是物件!!
但沒事不要這樣子,他是陣列就應該用循序式容器去儲存,
硬把他變成物件還用了key就是要強逼良家陣列上樹啊(上紅黑樹)

結論

淺淺地談這兩個容器的差別,太深入就無法了啊!
主要是要清楚陣列跟物件資料儲存方式就不一樣~

然後最後把陣列當成物件來使用等等,之後在類陣列的文章還會有更多欠打的行為,請敬請期待~

參考資料:

关联式容器
Day-24 Hash Table(雜湊表)
C++ STL关联式容器是什么?
JAVASCRIPT “ASSOCIATIVE ARRAYS” CONSIDERED HARMFUL


上一篇
Day4 前端蛇行撞牆記 - 讓你理解的 try...catch
下一篇
Day6 前端蛇行撞牆記 - 迭代(iteration)與她的姐妹們
系列文
前端蛇行撞牆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言