You need to create a program that will take an array of two numbers who are not necessarily in order, and then add not just those numbers but any numbers in between. For example, [3,1] will be the same as 1+2+3 and not just 3+1
您需要創建一個程序,該程序將採用兩個不一定按順序排列的數字組成的數組,然後不僅添加這些數字,還添加兩個數字。例如,[3,1]將與1 +2 +3相同,而不僅僅是3 1
其實就是我們以前學的等差數列求和。
Hints 提示Hint 1Use Math.max() to find the maximum value of two numbers.
Hint 2Use Math.min() to find the minimum value of two numbers.
Hint 3Remember to that you must add all the numbers in between so this would require a way to get those numbers.
Solutionscode ExplanationFirst create a variable to store the max number between two.
The same as before for the Smallest number.
We create a temporary variable to add the numbers.
Since the numbers might not be always in order, using max() and min() will help organize.
const sumAll = arr => { // Buckle up everything to one! const startNum = arr[0]; const endNum = arr[1];
// Get the count of numbers between the two numbers by subtracting them and add 1 to the absolute value. // ex. There are |1-4| + 1 = 4, (1, 2, 3, 4), 4 numbers between 1 and 4. const numCount = Math.abs(startNum - endNum) + 1;
// Using Arithmetic Progression summing formula const sum = ((startNum + endNum) * numCount) / 2; return sum;};Code ExplanationThe formula for calculating the sum of a continuous range is 「(startNum + endNum) * numCount / 2」.
arr[0] and arr[1] can either be startNum or endNum, order doesn’t matter.
We can get the count of numbers in range by 「Math.abs(arr[0] - arr[1]) + 1」.
Applying the formula by plugging in the numbers
Code ExplanationCreating a variable sum to store the sum of the elements.
Starting iteration of the loop from min element of given array and stopping when it reaches the max element.
Using a spread operator (…arr) allows passing the actual array to the function instead of one-by-one elements.
Javascript API
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/max
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/min
https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/statements/for
https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/global_objects/array/sort
https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/functions/arrow_functions
https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/operators/spread_syntax
詳情
Math.max() 函數返回一組數中的最大值。
語法Math.max(value1[,value2, ...])
參數返回值返回給定的一組數字中的最大值。如果給定的參數中至少有一個參數無法被轉換成數字,則會返回 NaN。
描述由於 max 是 Math 的靜態方法,所以應該像這樣使用:Math.max(),而不是創建的 Math 實例的方法(Math 不是構造函數)。
如果沒有參數,則結果為 - Infinity。
如果有任一參數不能被轉換為數值,則結果為 NaN。
示例使用 Math.max()Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20下面的方法使用 apply 方法尋找一個數值數組中的最大元素。getMaxOfArray([1,2,3]) 等價於 Math.max(1, 2, 3),但是你可以使用 getMaxOfArray ()作用於任意長度的數組上。
function getMaxOfArray(numArray) {
return Math.max.apply(null, numArray);
}或者通過使用最新的擴展語句spread operator,獲得數組中的最大值變得更容易。
var arr = [1, 2, 3];
var max = Math.max(...arr);Math.min() 返回零個或更多個數值的最小值。
語法Math.min([value1[,value2, ...]])
參數返回值給定數值中最小的數。如果任一參數不能轉換為數值,則返回NaN。
描述由於 min 是 Math 的靜態方法,所以應該像這樣使用:Math.min(),而不是作為你創建的 Math 實例的方法(Math 不是構造函數)。
如果沒有參數,結果為Infinity。
如果有任一參數不能被轉換為數值,結果為 NaN。
示例使用 Math.min()下例找出 x 和 y 的最小值,並把它賦值給 z:
var x = 10, y = -20;
使用 Math.min() 裁剪值(Clipping a value)
var z = Math.min(x, y);Math.min 經常用於裁剪一個值,以便使其總是小於或等於某個邊界值。例如:
var x = f(foo);
if (x > boundary) {
x = boundary;
}可以寫成:
var x = Math.min(f(foo), boundary);
另外,Math.max() 也可以被用來以相似的方式裁剪一個值。
for 語句用於創建一個循環,它包含了三個可選的表達式,這三個表達式被包圍在圓括號之中,使用分號分隔,後跟一個用於在循環中執行的語句(通常是一個塊語句)。
語法for ([initialization]; [condition]; [final-expression])
statementinitialization
一個表達式 (包含賦值語句) 或者變量聲明。典型地被用於初始化一個計數器。該表達式可以使用 var 或 let 關鍵字聲明新的變量,使用 var 聲明的變量不是該循環的局部變量,而是與 for 循環處在同樣的作用域中。用 let 聲明的變量是語句的局部變量。該表達式的結果無意義。
condition
一個條件表達式被用於確定每一次循環是否能被執行。如果該表達式的結果為 true,statement 將被執行。這個表達式是可選的。如果被忽略,那麼就被認為永遠為真。如果計算結果為假,那麼執行流程將被跳到 for 語句結構後面的第一條語句。
final-expression
每次循環的最後都要執行的表達式。執行時機是在下一次 condition 的計算之前。通常被用於更新或者遞增計數器變量。
statement
只要condition的結果為true就會被執行的語句。要在循環體內執行多條語句,使用一個塊語句({ ... })來包含要執行的語句。沒有任何語句要執行,使用一個空語句(;)。
示例使用 for以下例子聲明了變量 i 並被初始賦值為 0,for 語句檢查 i 的值是否小於 9,如果小於 9,則執行語句塊內的語句,並且最後將 i 的值增加 1。
for (var i = 0; i < 9; i++) {
可選的 for 表達式
console.log(i);
// more statements
}for 語句頭部圓括號中的所有三個表達式都是可選的。
例如,初始化塊中的表達式沒有被指定:
var i = 0;
for (; i < 9; i++) {
console.log(i);
// more statements
}像初始化塊一樣,條件塊也是可選的。如果省略此表達式,則必須確保在循環體內跳出,以防創建死循環。
for (var i = 0;; i++) {
console.log(i);
if (i > 3) break;
// more statements
}你當然可以忽略所有的表達式。同樣的,確保使用了 break >語句來跳出循環並且還要修改(增加)一個變量,使得 break 語句的條件在某個時候是真的。
var i = 0;
使用無語句的 for
for (;;) {
if (i > 3) break;
console.log(i);
i++;
}以下 for 循環計算 final-expression 部分中節點的偏移位置,它不需要執行一個 statement 或者一組 block statement ,因此使用了空語句。
function showOffsetPos(sId) {
var nLeft = 0, nTop = 0;
for (
var oItNode = document.getElementById(sId); /* initialization */
oItNode; /* condition */
nLeft += oItNode.offsetLeft, nTop += oItNode.offsetTop, oItNode = oItNode.offsetParent /* final-expression */
); /* 分號 semicolon */
console.log('Offset position of \'' + sId + '\' element:\n left: ' + nLeft + 'px;\n top: ' + nTop + 'px;');
}
/* Example call: */
showOffsetPos('content');
// Output:
// "Offset position of "content" element:
// left: 0px;
// top: 153px;"提示:這裡的分號是強制性的,是 JavaScript 中的少數幾種強制分號的情況。如果沒有分號,循環聲明之後的行將被視為循環語句。
sort() 方法用原地算法對數組的元素進行排序,並返回數組。默認排序順序是在將元素轉換為字符串,然後比較它們的UTF-16代碼單元值序列時構建的
由於它取決於具體實現,因此無法保證排序的時間和空間複雜性。
語法arr.sort([compareFunction])
參數返回值排序後的數組。請注意,數組已原地排序,並且不進行複製。
描述如果沒有指明 compareFunction ,那么元素會按照轉換為的字符串的諸個字符的Unicode位點進行排序。例如 "Banana" 會被排列到 "cherry" 之前。當數字按由小到大排序時,9 出現在 80 之前,但因為(沒有指明 compareFunction),比較的數字會先被轉換為字符串,所以在Unicode順序上 "80" 要比 "9" 要靠前。
如果指明了 compareFunction ,那麼數組會按照調用該函數的返回值排序。即 a 和 b 是兩個將要被比較的元素:
如果 compareFunction(a, b) 大於 0 , b 會被排列到 a 之前。
compareFunction(a, b) 必須總是對相同的輸入返回相同的比較結果,否則排序的結果將是不確定的。
所以,比較函數格式如下:
function compare(a, b) {
if (a < b ) { // 按某種排序標準進行比較, a 小於 b
return -1;
}
if (a > b ) {
return 1;
}
// a must be equal to b
return 0;
}要比較數字而非字符串,比較函數可以簡單的以 a 減 b,如下的函數將會將數組升序排列
function compareNumbers(a, b) {
return a - b;
}sort 方法可以使用 函數表達式 方便地書寫:
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
return a - b;
});
console.log(numbers);
也可以寫成:
var numbers = [4, 2, 5, 1, 3];
numbers.sort((a, b) => a - b);
console.log(numbers);
// [1, 2, 3, 4, 5]對象可以按照某個屬性排序:
var items = [
示例創建、顯示及排序數組
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: -12 },
{ name: 'Magnetic' },
{ name: 'Zeros', value: 37 }
];
// sort by value
items.sort(function (a, b) {
return (a.value - b.value)
});
// sort by name
items.sort(function(a, b) {
var nameA = a.name.toUpperCase(); // ignore upper and lowercase
var nameB = b.name.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});下述示例創建了四個數組,並展示原數組。之後對數組進行排序。對比了數字數組分別指定與不指定比較函數的結果。
var stringArray = ["Blue", "Humpback", "Beluga"];
var numericStringArray = ["80", "9", "700"];
var numberArray = [40, 1, 5, 200];
var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];
function compareNumbers(a, b)
{
return a - b;
}
console.log('stringArray:' + stringArray.join());
console.log('Sorted:' + stringArray.sort());
console.log('numberArray:' + numberArray.join());
console.log('Sorted without a compare function:'+ numberArray.sort());
console.log('Sorted with compareNumbers:'+ numberArray.sort(compareNumbers));
console.log('numericStringArray:'+ numericStringArray.join());
console.log('Sorted without a compare function:'+ numericStringArray.sort());
console.log('Sorted with compareNumbers:'+ numericStringArray.sort(compareNumbers));
console.log('mixedNumericArray:'+ mixedNumericArray.join());
console.log('Sorted without a compare function:'+ mixedNumericArray.sort());
console.log('Sorted with compareNumbers:'+ mixedNumericArray.sort(compareNumbers));該示例的返回結果如下。輸出顯示,當使用比較函數後,數字數組會按照數字大小排序。
stringArray: Blue,Humpback,Beluga
對非 ASCII 字符排序
Sorted: Beluga,Blue,Humpback
numberArray: 40,1,5,200
Sorted without a compare function: 1,200,40,5
Sorted with compareNumbers: 1,5,40,200
numericStringArray: 80,9,700
Sorted without a compare function: 700,80,9
Sorted with compareNumbers: 9,80,700
mixedNumericArray: 80,9,700,40,1,5,200
Sorted without a compare function: 1,200,40,5,700,80,9
Sorted with compareNumbers: 1,5,9,40,80,200,700當排序非 ASCII 字符的字符串(如包含類似 e, é, è, a, ä 等字符的字符串)。一些非英語語言的字符串需要使用 String.localeCompare。這個函數可以將函數排序到正確的順序。
var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];
使用映射改善排序
items.sort(function (a, b) {
return a.localeCompare(b);
});
// items is ['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']compareFunction 可能需要對元素做多次映射以實現排序,尤其當 compareFunction 較為複雜,且元素較多的時候,某些 compareFunction 可能會導致很高的負載。使用 map 輔助排序將會是一個好主意。基本思想是首先將數組中的每個元素比較的實際值取出來,排序後再將數組恢復。
// 需要被排序的數組
var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];
// 對需要排序的數字和位置的臨時存儲
var mapped = list.map(function(el, i) {
return { index: i, value: el.toLowerCase() };
})
// 按照多個值排序數組
mapped.sort(function(a, b) {
return +(a.value > b.value) || +(a.value === b.value) - 1;
});
// 根據索引得到排序的結果
var result = mapped.map(function(el){
return list[el.index];
});展開語法(Spread syntax), 可以在函數調用/數組構造時, 將數組表達式或者string在語法層面展開;還可以在構造字面量對象時, 將對象表達式按key-value的方式展開。(譯者注: 字面量一般指 [1, 2, 3] 或者 {name: "mdn"} 這種簡潔的構造方式)
語法函數調用:
myFunction(...iterableObj);
字面量數組構造或字符串:
[...iterableObj, '4', ...'hello', 6];
構造字面量對象時,進行克隆或者屬性拷貝(ECMAScript 2018規範新增特性):
let objClone = { ...obj };
示例在函數調用時使用展開語法等價於apply的方式如果想將數組元素迭代為函數參數,一般使用Function.prototype.apply 的方式進行調用。
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);有了展開語法,可以這樣寫:
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);所有參數都可以通過展開語法來傳值,也不限制多次使用展開語法。
function myFunction(v, w, x, y, z) { }
在 new 表達式中應用
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);使用 new 關鍵字來調用構造函數時,不能直接使用數組+ apply 的方式(apply 執行的是調用 [[Call]] , 而不是構造 [[Construct]])。當然, 有了展開語法, 將數組展開為構造函數的參數就很簡單了:
var dateFields = [1970, 0, 1]; // 1970年1月1日
var d = new Date(...dateFields);如果不使用展開語法, 想將數組元素傳給構造函數, 實現方式可能是這樣的:
function applyAndNew(constructor, args) {
構造字面量數組時使用展開語法構造字面量數組時更給力!
function partial () {
return constructor.apply(this, args);
};
if (typeof constructor.prototype === "object") {
partial.prototype = Object.create(constructor.prototype);
}
return partial;
}
function myConstructor () {
console.log("arguments.length: " + arguments.length);
console.log(arguments);
this.prop1="val1";
this.prop2="val2";
};
var myArguments = ["hi", "how", "are", "you", "mr", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);
console.log(new myConstructorWithArguments);
// (myConstructor構造函數中): arguments.length: 6
// (myConstructor構造函數中): ["hi", "how", "are", "you", "mr", null]
// ("new myConstructorWithArguments"中): {prop1: "val1", prop2: "val2"}沒有展開語法的時候,只能組合使用 push, splice, concat 等方法,來將已有數組元素變成新數組的一部分。有了展開語法, 通過字面量方式, 構造新數組會變得更簡單、更優雅:
var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
// ["head", "shoulders", "knees", "and", "toes"]和參數列表的展開類似, ... 在構造字面量數組時, 可以在任意位置多次使用.
數組拷貝(copy)var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4);
// arr2 此時變成 [1, 2, 3, 4]
// arr 不受影響提示: 實際上, 展開語法和 Object.assign() 行為一致, 執行的都是淺拷貝(只遍歷一層)。如果想對多維數組進行深拷貝, 下面的示例就有些問題了。
var a = [[1], [2], [3]];
連接多個數組
var b = [...a];
b.shift().shift(); // 1
// Now array a is affected as well: [[2], [3]]Array.concat 函數常用於將一個數組連接到另一個數組的後面。如果不使用展開語法, 代碼可能是下面這樣的:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// 將 arr2 中所有元素附加到 arr1 後面並返回
var arr3 = arr1.concat(arr2);使用展開語法:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];Array.unshift 方法常用於在數組的開頭插入新元素/數組. 不使用展開語法, 示例如下:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// 將 arr2 中的元素插入到 arr1 的開頭
Array.prototype.unshift.apply(arr1, arr2) // arr1 現在是 [3, 4, 5, 0, 1, 2]如果使用展開語法, 代碼如下: [請注意, 這裡使用展開語法創建了一個新的 arr1 數組, Array.unshift 方法則是修改了原本存在的 arr1 數組]:
var arr1 = [0, 1, 2];
構造字面量對象時使用展開語法
var arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1]; // arr1 現在為 [3, 4, 5, 0, 1, 2]Rest/Spread Properties for ECMAScript 提議(stage 4) 對 字面量對象 增加了展開特性。其行為是, 將已有對象的所有可枚舉(enumerable)屬性拷貝到新構造的對象中.
淺拷貝(Shallow-cloning, 不包含 prototype) 和對象合併, 可以使用更簡短的展開語法。而不必再使用 Object.assign() 方式.
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// 克隆後的對象: { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// 合併後的對象: { foo: "baz", x: 42, y: 13 }提示: Object.assign() 函數會觸發 setters,而展開語法則不會。
提示: 不能替換或者模擬 Object.assign() 函數:
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
const merge = ( ...objects ) => ( { ...objects } );
var mergedObj = merge ( obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }
var mergedObj = merge ( {}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }在這段代碼中, 展開操作符(spread operator)並沒有按預期的方式執行: 而是先將多個解構變為剩餘參數(rest parameter), 然後再將剩餘參數展開為字面量對象.
只能用於可迭代對象在數組或函數參數中使用展開語法時, 該語法只能用於 可迭代對象:
var obj = {'key1': 'value1'};
展開多個值
var array = [...obj]; // TypeError: obj is not iterable在函數調用時使用展開語法,請注意不能超過 JavaScript 引擎限制的最大參數個數。更多詳細信息,請參考: apply()。
剩餘語法(剩餘參數)剩餘語法(Rest syntax) 看起來和展開語法完全相同,不同點在於, 剩餘參數用於解構數組和對象。從某種意義上說,剩餘語法與展開語法是相反的:展開語法將數組展開為其中的各個元素,而剩餘語法則是將多個元素收集起來並「凝聚」為單個元素。請參考: 剩餘參數。
❤️愛心三連擊
1.看到這裡了就點個在看支持下吧,你的「點讚,在看」是我們創作的動力。
2.關注公眾號圖靈IT青年俱樂部
回復「沙龍」參加線上線下技術沙龍; 回復「python」參加python訓練營; 回復「java」參加2020版企業實戰Java精英線下課程; 回復「圖靈編程」了解圖靈IT青年俱樂部;
3.也可添加微信【17612567626】,一起成長。