iT邦幫忙

1

關於javascript array.filter() 函數

想請教一下 下面程式碼
filterArray01 與 filterArray02 最終都是空陣列
也就是說沒有符合的值
是因為我的索引非正整數的關係?(只能用foreach嗎?)
還是有其他我沒注意的問題?
謝謝

var mainArray = new Array();
mainArray['a']=1;
mainArray['b']=2;
mainArray['c']=3;
mainArray['d']=4;

var filterArray01 = mainArray.filter( function(value,key){
if(value % 2 ==0) return true;
});

var filterArray02 = mainArray.filter( function(value,key){
if(key == 'b') return true;
});
看更多先前的討論...收起先前的討論...
ccutmis iT邦高手 8 級 ‧ 2019-10-04 23:25:41 檢舉
最常見的陣列存取是這樣用:
mainArray=[];
mainArray.push(1);
mainArray.push(2);
mainArray.push(3);
mainArray.push(4);
var filterArray01 = mainArray.filter( function(value){
if(value %2==0) return true;
});
console.log(filterArray01);
xWinter iT邦新手 5 級 ‧ 2019-10-04 23:31:18 檢舉
有測過這樣的寫法能成功回傳
所以才會想說是索引非正整數的關係導致失敗嗎
看大大們的回答是陣列與物件的差別...
再研究研究...
dragonH iT邦超人 6 級 ‧ 2019-10-04 23:33:36 檢舉
如果你是想要對 object 也進行一樣的操作也是可以

不過就不會是直接使用 filter
ccutmis iT邦高手 8 級 ‧ 2019-10-04 23:38:44 檢舉
這個是JAVASCRIPT自動轉型別造成的,
主要在於你對陣列跟物件長相的存讀規則不熟,
原來的本文裡面你存進去的已經不是單純的數值或字串了,
而是存入物件的寫法"KEY":"VALUE",
JAVASCRIPT會自動把=號左邊的東西轉型別,舉個例
a=1; /*這時a是 number */
a='hello I'm string now!'; /*這時a變成 string了 */
所以你懂了嗎 ?
var mainArray = new Array(); /*是陣列*/
mainArray['a']=1; /*被強制轉物件了 */
大概事情是這麼發生的...
但是陣列裡也是可以存物件的,你只是寫在外面把陣列轉成物件了
改成這樣寫就是把物件寫進陣列裡面:
var mainArray = new Array();
mainArray.push({'a':1});
mainArray.push({'b':2});
...
xWinter iT邦新手 5 級 ‧ 2019-10-04 23:42:34 檢舉
請教一下其中有個索引值非整數是算陣列還是物件?
測試發現其中一個索引值為非正整數(ex:'a')是能成功返回的 只是沒有返回索引為'a'對應的值
ccutmis iT邦高手 8 級 ‧ 2019-10-04 23:56:49 檢舉
遍歷物件可能要上網搜一下例如這個
https://www.itread01.com/content/1544852723.html
dragonH iT邦超人 6 級 ‧ 2019-10-05 00:02:39 檢舉
>測試發現其中一個索引值為非正整數(ex:'a')是能成功返回的 只是沒有返回索引為'a'對應的值

可以貼一下你的 code嗎

來討論一下XD
dragonH iT邦超人 6 級 ‧ 2019-10-05 00:06:16 檢舉
想要在你的 mainArray

得到你想要的結果

可以用

Object.values(mainArray).filter()
xWinter iT邦新手 5 級 ‧ 2019-10-05 00:07:38 檢舉
var mainArray = new Array();
mainArray[0]=1; mainArray[1]=2; mainArray[2]=3; mainArray['a']=4;

var filterArray01 = mainArray.filter( function(value,key){
if(value % 2 ==0) return true;
});
filterArray01 有值 為 [0]=2
ccutmis iT邦高手 8 級 ‧ 2019-10-05 00:13:25 檢舉
為何不改這樣就好了...
mainArray[0]=1; mainArray[1]=2; mainArray[2]=3; mainArray[3]=4;
返回值有2,4

你寫的前三個是陣列的寫入沒問題,但是mainArray['a']=4;這個就又會遇到跟之前一樣的問題,javascript動態轉型別這種特性其實是很不好的,要儘量避免才不會造成你在除錯上面的困難,比如說你設了一個字串變數
var tmpString="I'm a string";
雖然你知道 tmpString =5; //它就變成數字變數,但是最好是讓它從一而終,不然你除錯到一半還要分神想這變數剛才是字串,現在是數字,等等又可能變物件... o_o"
xWinter iT邦新手 5 級 ‧ 2019-10-05 00:16:08 檢舉
只是測試這樣混合的結果會怎樣而已
dragonH iT邦超人 6 級 ‧ 2019-10-05 00:16:33 檢舉
這個我還真不會解釋...

https://codepen.io/dragonH/pen/eYYOqEv?editors=0010

不過從範例可以看到

mainArray 的長度只有 3

filter 也沒有執行到 ['a']=4; 的部分

用 foreach 甚至會直接 throw error
xWinter iT邦新手 5 級 ‧ 2019-10-05 00:16:35 檢舉
Object.values(mainArray).filter() 是能達到我想要的功能,
雖然沒有辦法判斷key 只能判斷 value
不過 我還是先研究研究 陣列與物件差別好了
謝謝2位回答
dragonH iT邦超人 6 級 ‧ 2019-10-05 00:19:58 檢舉
key 有 object.keys() 可以用
xWinter iT邦新手 5 級 ‧ 2019-10-05 00:21:05 檢舉
了解 謝謝你的回答 我再來試試看
ccutmis iT邦高手 8 級 ‧ 2019-10-05 00:40:03 檢舉
補充一下 物件的key通常會設有獨特意義,比如說:
var tradeObj={ "tradeDate":"20191005",
"tradeTitle":"股名,代碼,開盤,最高,最低,收盤",
"tradeData":
[["泥台","1011","xxx","xxx","xxx","xxx"],
["泥亞","2011","xxx","xxx","xxx","xxx"],
["泥家","3011","xxx","xxx","xxx","xxx"]]
};
console.log(tradeObj['tradeDate']); // 20191005
console.log(tradeObj['tradeData']); //這個傳回的就是陣列 可以用filter過濾
var tmpArr=(tradeObj['tradeData']).filter( function(value){
if(parseInt(value[1])>2000) return value; /* 代碼大於'2000' */
});
console.log(tmpArr);
熟悉基礎的你才有辦法去活用...
xWinter iT邦新手 5 級 ‧ 2019-10-05 10:11:35 檢舉
個人對表面上的理解
物件為 屬性:值
其中 值 可以是不同型態
tradeObj 為物件
"tradeDate"、"tradeTitle"、"tradeData" 皆為屬性
"20191005"、"股名,代碼,開盤,最高,最低,收盤" 為值,型態為string
[["泥台","1011","xxx","xxx","xxx","xxx"],
["泥亞","2011","xxx","xxx","xxx","xxx"],
["泥家","3011","xxx","xxx","xxx","xxx"]]
為值,型態為陣列
此陣列內容也是陣列
tradeDate[0]=["泥台","1011","xxx","xxx","xxx","xxx"]
tradeDate[1]=["泥亞","2011","xxx","xxx","xxx","xxx"]
tradeDate[2]=["泥家","3011","xxx","xxx","xxx","xxx"]
所以可以進行一些陣列操作

看到樓下有大大說的
當寫出 myArray['x']=1 這類的敘述時,
其實是添加一個 myArray.x 屬性。但不影響原先 Array 的功能。
我好像對
var mainArray = new Array();
mainArray[0]=1; mainArray[1]=2; mainArray[2]=3; mainArray['a']=4;
這種混和的陣列?物件? 可做一些陣列操作處理,有些微理解了
ccutmis iT邦高手 8 級 ‧ 2019-10-05 10:25:22 檢舉
陣列裡面本來就可以包物件,
例如 var tmpArr=[0, 1, 'ABC', {'fruit':'apple'}
物件裡面也可以包陣列,
例如上面的 tradeObj ,

而mainArray[0]=1; mainArray[1]=2; mainArray[2]=3; mainArray['a']=4;
這種方式我是不建議的,那個不是把字典加入陣列,
而是讓原本的陣列多出字典的特性,有問題的寫法只會埋下更多問題的種子,
不過你是在練習我就不多說了。

2 個回答

1
dragonH
iT邦超人 6 級 ‧ 2019-10-04 23:03:06
最佳解答

你的 array 跟我認識的 array 不太一樣

你可以補上

typeof mainArray

看 mainArray 的 type 變成什麼了


filter MDN DOC

var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

補充下看到的

mix array with object 的討論

看更多先前的回應...收起先前的回應...
ccutmis iT邦高手 8 級 ‧ 2019-10-04 23:18:34 檢舉

陣列當物件用,物件當陣列用...
最近的邦友真的愈來愈有創意了~
/images/emoticon/emoticon38.gif

dragonH iT邦超人 6 級 ‧ 2019-10-04 23:22:11 檢舉

/images/emoticon/emoticon37.gif

入門就挑到 js 這個大魔王

也算他運氣不好XD

xWinter iT邦新手 5 級 ‧ 2019-10-04 23:23:28 檢舉

typeof mainArray 是物件
可是試了一下
var colors = new Array("Red", "Green", "Blue");
typeof colors 也是物件
不過colors.filter(function(value,key){if(value=='Green')return true;});
卻能成功返回
老實說還是不懂.....

dragonH iT邦超人 6 級 ‧ 2019-10-04 23:28:36 檢舉

我發現我用 typeof 講

好像不太 ok

應該說用

Array.isArray()

會比較好

typeof MDN

colors 可以

因為他是 array

xWinter iT邦新手 5 級 ‧ 2019-10-04 23:40:46 檢舉

Array.isArray(mainArray)
<- true
..... 所以我的mainArray是物件還是陣列.....

dragonH iT邦超人 6 級 ‧ 2019-10-05 00:01:05 檢舉

剛試了其他方法

也都是回傳 mainArray 是 array

不過如果測試

console.log(mainArray.length)

會發現它是一個 長度為 0 的 array

也就是說

你的 filter 其實都沒用

0
淺水員
iT邦新手 1 級 ‧ 2019-10-05 00:46:22

綜合上面的討論,我認為:

  1. Array 本身屬於一種 Object。
  2. 當寫出 myArray['x']=1 這類的敘述時,其實是添加一個 myArray.x 屬性。但不影響原先 Array 的功能。

也許這可以參考:繼承與原型鏈

看更多先前的回應...收起先前的回應...
ccutmis iT邦高手 8 級 ‧ 2019-10-05 01:16:34 檢舉

這個其實算是javascript語言先天的bug,
已經宣告是陣列的變數,
正常來說就是使用它的push()方法或是由陣列索引賦值
來增加或修改陣列元素,
用物件添加屬性的方式雖然在這邊不會報錯,
但是以工程師的人腦編譯器來說應該已經跳出紅色的X了才對。
/images/emoticon/emoticon77.gif

如果你用了但人腦編譯器沒跳出紅色的X,那可能要找華農兄弟...
/images/emoticon/emoticon48.gif

dragonH iT邦超人 6 級 ‧ 2019-10-05 09:15:28 檢舉

Array 本來就是一個特別的 object

這應該沒啥問題

我比較好奇的是

透過 myArray['x']=1 賦值

然後再使用 forEach filter 那些

竟然不會有 error

/images/emoticon/emoticon11.gif

淺水員 iT邦新手 1 級 ‧ 2019-10-05 10:06:54 檢舉

forEach filter 不知道 x 的存在吧?一種私生子見不得光的味道。

dragonH iT邦超人 6 級 ‧ 2019-10-05 10:15:13 檢舉

/images/emoticon/emoticon82.gif

我要發表回答

立即登入回答