<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 4數組 ### 檢查變量的類型是否為數組 ### 問題 你希望檢查一個變量是否為一個數組。 ~~~ myArray = [] console.log typeof myArray // outputs 'object' ~~~ “typeof” 運算符為數組輸出了一個錯誤的結果。 ### 解決方案 使用下面的代碼: ~~~ typeIsArray = Array.isArray || ( value ) -> return {}.toString.call( value ) is '[object Array]' ~~~ 為了使用這個,像下面這樣調用 typeIsArray 就可以了。 ~~~ myArray = [] typeIsArray myArray // outputs true ~~~ ### 討論 上面方法取自 "the Miller Device"。另外一個方式是使用 Douglas Crockford 的片段。 ~~~ typeIsArray = ( value ) -> value and typeof value is 'object' and value instanceof Array and typeof value.length is 'number' and typeof value.splice is 'function' and not ( value.propertyIsEnumerable 'length' ) ~~~ ### 將數組連接 ### 問題 你希望將兩個數組連接到一起。 ### 解決方案 在 JavaScript 中,有兩個標準方法可以用來連接數組。 第一種是使用 JavaScript 的數組方法 concat(): ~~~ array1 = [1, 2, 3] array2 = [4, 5, 6] array3 = array1.concat array2 # => [1, 2, 3, 4, 5, 6] ~~~ 需要指出的是 array1 沒有被運算修改。連接后形成的新數組的返回值是一個新的對象。 如果你希望在連接兩個數組后不產生新的對象,那么你可以使用下面的技術: ~~~ array1 = [1, 2, 3] array2 = [4, 5, 6] Array::push.apply array1, array2 array1 # => [1, 2, 3, 4, 5, 6] ~~~ 在上面的例子中,Array.prototype.push.apply(a, b) 方法修改了 array1 而沒有產生一個新的數組對象。 在 CoffeeScript 中,我們可以簡化上面的方式,通過給數組創建一個新方法 merge(): ~~~ Array::merge = (other) -> Array::push.apply @, other ? array1 = [1, 2, 3] array2 = [4, 5, 6] array1.merge array2 array1 # => [1, 2, 3, 4, 5, 6] ~~~ 另一種方法,我可以直接將一個 CoffeeScript splat(array2) 放入 push() 中,避免了使用數組原型。 ~~~ array1 = [1, 2, 3] array2 = [4, 5, 6] array1.push array2... array1 # => [1, 2, 3, 4, 5, 6] ~~~ 一個更加符合語言習慣的方法是在一個數組語言中直接使用 splat 運算符(...)。這可以用來連接任意數量的數組。 ~~~ array1 = [1, 2, 3] array2 = [4, 5, 6] array3 = [array1..., array2...] array3 # => [1, 2, 3, 4, 5, 6] ~~~ ### 討論 CoffeeScript 缺少了一種用來連接數組的特殊語法,但是 concat() 和 push() 是標準的 JavaScript 方法。 ### 由數組創建一個對象詞典 ### 問題 你有一組對象,例如: ~~~ cats = [ { name: "Bubbles" age: 1 }, { name: "Sparkle" favoriteFood: "tuna" } ] ~~~ 但是你想讓它像詞典一樣,可以通過關鍵字訪問它,就像使用 cats["Bubbles"]。 ### 解決方案 你需要將你的數組轉換為一個對象。通過這樣使用 reduce: ~~~ # key = The key by which to index the dictionary ? Array::toDict = (key) -> @reduce ((dict, obj) -> dict[ obj[key] ] = obj if obj[key]?; return dict), {} ~~~ 使用它時像下面這樣: ~~~ catsDict = cats.toDict('name') catsDict["Bubbles"] # => { age: 1, name: "Bubbles" } ~~~ ### 討論 另一種方法是使用數組推導: ~~~ Array::toDict = (key) -> dict = {} dict[obj[key]] = obj for obj in this when obj[key]? dict ~~~ 如果你使用 Underscore.js,你可以創建一個 mixin: ~~~ _.mixin toDict: (arr, key) -> throw new Error('_.toDict takes an Array') unless _.isArray arr _.reduce arr, ((dict, obj) -> dict[ obj[key] ] = obj if obj[key]?; return dict), {} catsDict = _.toDict(cats, 'name') catsDict["Sparkle"] # => { favoriteFood: "tuna", name: "Sparkle" } ~~~ ### 由數組創建一個字符串 ### 問題 你想由數組創建一個字符串。 ### 解決方案 使用 JavaScript 的數組方法 toString(): ~~~ ["one", "two", "three"].toString() # => 'one,two,three' ~~~ ### 討論 toString() 是一個標準的 JavaScript 方法。不要忘記圓括號。 ### 定義數組范圍 ### 問題 你想定義一個數組的范圍。 ### 解決方案 在 CoffeeScript 中,有兩種方式定義數組元素的范圍。 ~~~ myArray = [1..10] # => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] ~~~ ~~~ myArray = [1...10] # => [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ~~~ 要想反轉元素的范圍,則可以寫成下面這樣。 ~~~ myLargeArray = [10..1] # => [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ] ~~~ ~~~ myLargeArray = [10...1] # => [ 10, 9, 8, 7, 6, 5, 4, 3, 2 ] ~~~ ### 討論 包含范圍以 “..” 運算符定義,包含最后一個值。 排除范圍以 “...” 運算符定義,并且通常忽略最后一個值。 ### 篩選數組 ### 問題 你想要根據布爾條件來篩選數組。 ### 解決方案 使用 `Array.filter (ECMAScript 5): array = [1..10]` ~~~ array.filter (x) -> x > 5 # => [6,7,8,9,10] ~~~ 在 EC5 之前的實現中,可以通過添加一個篩選函數擴展 Array 的原型,該函數接受一個回調并對自身進行過濾,將回調函數返回 true 的元素收集起來。 ~~~ # 擴展 Array 的原型 ? Array::filter = (callback) -> element for element in this when callback(element) ? array = [1..10] ? # 篩選偶數 ? filtered_array = array.filter (x) -> x % 2 == 0 # => [2,4,6,8,10] ? ? # 過濾掉小于或等于5的元素 ? gt_five = (x) -> x > 5 filtered_array = array.filter gt_five # => [6,7,8,9,10] ~~~ ### 討論 這個方法與 Ruby 的 Array 的 #select 方法類似。 ### 列表推導 ### 問題 你有一個對象數組,想將它們映射到另一個數組,類似于 Python 的列表推導。 ### 解決方案 使用列表推導,但不要忘記還有 [mapping-arrays](http://coffeescript-cookbook.github.io/chapters/arrays/mapping-arrays) 。 ~~~ electric_mayhem = [ { name: "Doctor Teeth", instrument: "piano" }, { name: "Janice", instrument: "lead guitar" }, { name: "Sgt. Floyd Pepper", instrument: "bass" }, { name: "Zoot", instrument: "sax" }, { name: "Lips", instrument: "trumpet" }, { name: "Animal", instrument: "drums" } ] ? names = (muppet.name for muppet in electric_mayhem) # => [ 'Doctor Teeth', 'Janice', 'Sgt. Floyd Pepper', 'Zoot', 'Lips', 'Animal' ] ~~~ ### 討論 因為 CoffeeScript 直接支持列表推導,在你使用一個 Python 的語句時,他們會很好地起到作用。對于簡單的映射,列表推導具有更好的可讀性。但是對于復雜的轉換或鏈式映射,映射數組可能更合適。 ### 映射數組 ### 問題 你有一個對象數組,想把這些對象映射到另一個數組中,就像 Ruby 的映射一樣。 ### 解決方案 使用 map() 和匿名函數,但不要忘了還有列表推導。 ~~~ electric_mayhem = [ { name: "Doctor Teeth", instrument: "piano" }, { name: "Janice", instrument: "lead guitar" }, { name: "Sgt. Floyd Pepper", instrument: "bass" }, { name: "Zoot", instrument: "sax" }, { name: "Lips", instrument: "trumpet" }, { name: "Animal", instrument: "drums" } ] ? names = electric_mayhem.map (muppet) -> muppet.name # => [ 'Doctor Teeth', 'Janice', 'Sgt. Floyd Pepper', 'Zoot', 'Lips', 'Animal' ] ~~~ ### 討論 因為 CoffeeScript 支持匿名函數,所以在 CoffeeScript 中映射數組就像在 Ruby 中一樣簡單。映射在 CoffeeScript 中是處理復雜轉換和連綴映射的好方法。如果你的轉換如同上例中那么簡單,那可能將它當成[列表推導](http://coffeescript-cookbook.github.io/chapters/arrays/list-comprehensions) 看起來會清楚一些。 ### 數組最大值 ### 問題 你需要找出數組中包含的最大的值。 ### 解決方案 你可以使用 JavaScript 實現,在列表推導基礎上使用 Math.max(): ~~~ Math.max [12, 32, 11, 67, 1, 3]... # => 67 ~~~ 另一種方法,在 ECMAScript 5 中,可以使用 Array 的 reduce 方法,它與舊的 JavaScript 實現兼容。 ~~~ # ECMAScript 5 ? [12,32,11,67,1,3].reduce (a,b) -> Math.max a, b # => 67 ~~~ ### 討論 Math.max 在這里比較兩個數值,返回其中較大的一個。省略號 (...) 將每個數組價值轉化為給函數的參數。你還可以使用它與其他帶可變數量的參數進行討論,如執行 console.log 。 ### 歸納數組 ### 問題 你有一個對象數組,想要把它們歸納為一個值,類似于 Ruby 中的 reduce() 和 reduceRight() 。 ### 解決方案 可以使用一個匿名函數包含 Array 的 reduce() 和 reduceRight() 方法,保持代碼清晰易懂。這里歸納可能會像對數值和字符串應用 + 運算符那么簡單。 ~~~ [1,2,3,4].reduce (x,y) -> x + y # => 10 ? ? ["words", "of", "bunch", "A"].reduceRight (x, y) -> x + " " + y # => 'A bunch of words' ~~~ 或者,也可能更復雜一些,例如把列表中的元素聚集到一個組合對象中。 ~~~ people = { name: 'alec', age: 10 } { name: 'bert', age: 16 } { name: 'chad', age: 17 } ? people.reduce (x, y) -> x[y.name]= y.age x , {} # => { alec: 10, bert: 16, chad: 17 } ~~~ #### 討論 Javascript 1.8 中引入了 reduce 和 reduceRight ,而 Coffeescript 為匿名函數提供了簡單自然的表達語法。二者配合使用,可以把集合的項合并為組合的結果。 ### 刪除數組中的相同元素 ### 問題 你想從數組中刪除相同元素。 ### 解決方案 ~~~ Array::unique = -> output = {} output[@[key]] = @[key] for key in [0...@length] value for key, value of output ? [1,1,2,2,2,3,4,5,6,6,6,"a","a","b","d","b","c"].unique() # => [ 1, 2, 3, 4, 5, 6, 'a', 'b', 'd', 'c' ] ~~~ ### 討論 在 JavaScript 中有很多的獨特方法來實現這一功能。這一次是基于“最快速的方法來查找數組的唯一元素”,出自[這里](http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/) 。 > 注意: 延長本機對象通常被認為是在 JavaScript 不好的做法,即便它在 Ruby 語言中相當普遍, (參考:[Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/) ### 反轉數組 ### 問題 你想要反轉數組元素。 ### 解決方案 使用 JavaScript Array 的 reverse() 方法: ~~~ ["one", "two", "three"].reverse() # => ["three", "two", "one"] ~~~ #### 討論 reverse() 是標準的 JavaScript 方法,別忘了帶圓括號。 ### 打亂數組中的元素 ### 問題 你想打亂數組中的元素。 ### 解決方案 [ Fisher-Yates shuffle ](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) 是一種高效、公正的方式來讓數組中的元素隨機化。這是一個相當簡單的方法:在列表的結尾處開始,用一個隨機元素交換最后一個元素列表中的最后一個元素。繼續下一個并重復操作,直到你到達列表的起始端,最終列表中所有的元素都已打亂。這 [ Fisher-Yates shuffle Visualization ](http://bost.ocks.org/mike/shuffle/) 可以幫助你理解算法。 ~~~ shuffle = (source) -> # Arrays with < 2 elements do not shuffle well. Instead make it a noop. return source unless source.length >= 2 # From the end of the list to the beginning, pick element `index`. for index in [source.length-1..1] # Choose random element `randomIndex` to the front of `index` to swap with. randomIndex = Math.floor Math.random() * (index + 1) # Swap `randomIndex` with `index`, using destructured assignment [source[index], source[randomIndex]] = [source[randomIndex], source[index]] source ? shuffle([1..9]) # => [ 3, 1, 5, 6, 4, 8, 2, 9, 7 ] ~~~ ### 討論 #### 一種錯誤的方式 有一個很常見但是錯誤的打亂數組的方式:通過隨機數。 ~~~ shuffle = (a) -> a.sort -> 0.5 - Math.random() ~~~ 如果你做了一個隨機的排序,你應該得到一個序列隨機的順序,對吧?甚至[微軟也用這種隨機排序算法](http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html) 。原來,[這種隨機排序算法產生有偏差的結果](http://blog.codinghorror.com/the-danger-of-naivete/) ,因為它存在一種洗牌的錯覺。隨機排序不會導致一個工整的洗牌,它會導致序列排序質量的參差不齊。 #### 速度和空間的優化 以上的解決方案處理速度是不一樣的。該列表,當轉換成 JavaScript 時,比它要復雜得多,變性分配比處理裸變量的速度要慢得多。以下代碼并不完善,并且需要更多的源代碼空間 … 但會編譯量更小,運行更快: ~~~ shuffle = (a) -> i = a.length while --i > 0 j = ~~(Math.random() * (i + 1)) # ~~ is a common optimization for Math.floor t = a[j] a[j] = a[i] a[i] = t a ~~~ #### 擴展 Javascript 來包含亂序數組 下面的代碼將亂序功能添加到數組原型中,這意味著你可以在任何希望的數組中運行它,并以更直接的方式來運行它。 ~~~ Array::shuffle ?= -> if @length > 1 then for i in [@length-1..1] j = Math.floor Math.random() * (i + 1) [@[i], @[j]] = [@[j], @[i]] this ? [1..9].shuffle() # => [ 3, 1, 5, 6, 4, 8, 2, 9, 7 ] ~~~ > 注意: 雖然它像在 Ruby 語言中相當普遍,但是在 JavaScript 中擴展本地對象通常被認為是不太好的做法 ( 參考: [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/) 正如提到的,以上的代碼的添加是十分安全的。它僅僅需要添 Array :: shuffle 如果它不存在,就要添加賦值運算符 (? =) 。這樣,我們就不會重寫到別人的代碼,或是本地瀏覽器的方式。 > 同時,如果你認為你會使用很多的實用功能,可以考慮使用一個工具庫,像 [ Lo-dash](https://lodash.com/) 。他們有很多功能,像跨瀏覽器的簡潔高效的地圖。 [Underscore](http://underscorejs.org/) 也是一個不錯的選擇。 ### 檢測每個元素 ### 問題 你希望能夠在特定的情況下檢測出在數組中的每個元素。 ### 解決方案 使用 Array.every (ECMAScript 5): ~~~ evens = (x for x in [0..10] by 2) ? evens.every (x)-> x % 2 == 0 # => true ~~~ Array.every 被加入到 Mozilla 的 Javascript 1.6 ,ECMAScript 5 標準。如果你的瀏覽器支持,但仍無法實施 EC5 ,那么請檢查 [ _.all from underscore.js](http://documentcloud.github.io/underscore/) 。 對于一個真實例子,假設你有一個多選擇列表,如下: ~~~ <select multiple id="my-select-list"> <option>1</option> <option>2</option> <option>Red Car</option> <option>Blue Car</option> </select> ~~~ 現在你要驗證用戶只選擇了數字。讓我們利用 array.every : ~~~ validateNumeric = (item)-> parseFloat(item) == parseInt(item) && !isNaN(item) ? values = $("#my-select-list").val() ? values.every validateNumeric ~~~ ### 討論 這與 Ruby 中的 Array #all? 的方法很相似。 ### 使用數組來交換變量 ### 問題 你想通過數組來交換變量。 ### 解決方案 使用 CoffeeScript 的解構賦值語法: ~~~ a = 1 b = 3 ? [a, b] = [b, a] ? a # => 3 ? ? b # => 1 ~~~ ### 討論 解構賦值可以不依賴臨時變量實現變量值的交換。 這種語法特別適合在遍歷數組的時候只想迭代最短數組的情況: ~~~ ray1 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ray2 = [ 5, 9, 14, 20 ] ? intersection = (a, b) -> [a, b] = [b, a] if a.length > b.length value for value in a when value in b ? intersection ray1, ray2 # => [ 5, 9 ] ? ? intersection ray2, ray1 # => [ 5, 9 ] ~~~ ### 對象數組 ### 問題 你想要得到一個與你的某些屬性匹配的數組對象。 你有一系列的對象,如: ~~~ cats = [ { name: "Bubbles" favoriteFood: "mice" age: 1 }, { name: "Sparkle" favoriteFood: "tuna" }, { name: "flyingCat" favoriteFood: "mice" age: 1 } ] ~~~ 你想用某些特征來濾出想要的對象。例如:貓的位置 ({ 年齡: 1 }) 或者貓的位置 ({ 年齡: 1 , 最愛的食物: "老鼠" }) ### 解決方案 你可以像這樣來擴展數組: ~~~ Array::where = (query) -> return [] if typeof query isnt "object" hit = Object.keys(query).length @filter (item) -> match = 0 for key, val of query match += 1 if item[key] is val if match is hit then true else false ? cats.where age:1 # => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 },{ name: 'flyingCat', favoriteFood: 'mice', age: 1 } ] ? ? cats.where age:1, name: "Bubbles" # => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 } ] ? ? cats.where age:1, favoriteFood:"tuna" # => [] ~~~ ### 討論 這是一個確定的匹配。我們能夠讓匹配函數更加靈活: ~~~ Array::where = (query, matcher = (a,b) -> a is b) -> return [] if typeof query isnt "object" hit = Object.keys(query).length @filter (item) -> match = 0 for key, val of query match += 1 if matcher(item[key], val) if match is hit then true else false ? cats.where name:"bubbles" # => [] ? # it's case sensitive ? ? cats.where name:"bubbles", (a, b) -> "#{ a }".toLowerCase() is "#{ b }".toLowerCase() # => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 } ] ? # now it's case insensitive ~~~ 處理收集的一種方式可以被叫做 “find” ,但是像 underscore 或者 lodash 這些庫把它叫做 “where” 。 ### 類似 Python 的 zip 函數 ### 問題 你想把多個數組連在一起,生成一個數組的數組。換句話說,你需要實現與 Python 中的 zip 函數類似的功能。 Python 的 zip 函數返回的是元組的數組,其中每個元組中包含著作為參數的數組中的第 i 個元素。 ### 解決方案 使用下面的 CoffeeScript 代碼: ~~~ # Usage: zip(arr1, arr2, arr3, ...) ? zip = () -> lengthArray = (arr.length for arr in arguments) length = Math.max.apply(Math, lengthArray) argumentLength = arguments.length results = [] for i in [0...length] semiResult = [] for arr in arguments semiResult.push arr[i] results.push semiResult return results ? zip([0, 1, 2, 3], [0, -1, -2, -3]) # => [[0, 0], [1, -1], [2, -2], [3, -3]] ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看