如何不使用loop循環,創建一個長度為100的數組,並且每個元素的值等於它的下標?
這是昨天參加阿里筆試的題目,我當初寫下的答案如下:
var a = new Array(100); a = a.map(function(item, index) { return index;});本以為是正確的,但是後來回到學校後,使用控制台列印一下,竟然是一個空數組,如下:
求大神指教!
這東西生成的是稀疏數組。
按照你的思路。在Array(100)的基礎上,改成Array.from(Array(100))就可以返回密集數組了。不過他說不能用loop,用map會不會太直接啊,講道理map也算loop吧 。要我就用sort之類的會比較委婉。
不過出題人應該把遞歸給禁用掉才好。
----------------------------------------補充一下,創建一個空的密集數組最正確姿勢應該用:
Array.from({length:100})
Array.apply(null,{length:100})
會加分;
ES6可以用spread拓展運算符:[...Array(100)]
/*
* Object.keys(Array.from({length:100}));
@missFM 說得對,Array.from是es6的,不能這裡用
*/
Object.keys(Array.apply(null,{length:100}));
// 這裡補充說明一下為什麼我認為Array.apply(null,{length:100})會加分,原因在於{length:100}這種寫法屬於鴨子類型,是es5才支持,老瀏覽器必須傳一個真正的Array(100) 這樣進去才行,相對比較消耗性能。
Array.from(Array(100).keys())
或者
[...Array(100).keys()]
這應該是最短代碼的了
----------------------------------------
有一個很污的寫法:Number.prototype[Symbol.iterator] = function() {
return {
v: 0,
e: this,
next() {
return {
value: this.v++,
done: this.v &> this.e
}
}
}
}
然後就可以:
[...100]
用所謂函數式語言的,用遞歸實現循環的思路就行了
function reduce(prev, curr) {
if (curr &>= 100) {
return prev
}
prev.push(curr)
return reduce(prev, curr + 1)
}
var arr = reduce([], 0)
當然,這是最樸素的方法,可以玩的方法還是挺多的
追加:當然上面的那個實在太無聊了,我本來想用goto的,結果想起來,JS不支持goto,fuck JS,寶寶不開心了::&>_&<::。那麼我只能讓它「支持」goto了,於是有了下面的代碼function VM() {
this.stack = []
this.cs = []
this.pc = 0
this.ax = undefined
this.bx = undefined
}
VM.prototype.run = function(codes) {
this.cs = codes
this.pc = 0
return this.interpret()
}
VM.prototype.interpret = function() {
var vm = this
var instruction = vm.cs[vm.pc]
var op = instruction[0]
var ops = instruction.slice(1)
switch (op) {
case "jl":
if (vm.ax &< vm.bx) {
vm.pc = ops[0]
return vm.interpret()
}
case "inc":
vm.ax++
break
case "ld":
vm[ops[0]] = ops[1]
break
case "push":
vm.stack.push(vm[ops[0]])
break
case "pop":
vm[ops[0]] = vm.stack.pop()
break
case "arr_push":
vm.bx.push(vm.ax)
break
case "ret":
return vm.ax
break
default:
throw "wtf??"
}
vm.pc++
return vm.interpret()
}
function make_a_100_len_array_without_fucking_loop() {
var codes = [
["ld", "ax", 0], // 0
["ld", "bx", []], // 1
["push", "bx"], // 2
["push", "ax"], // 3
["pop", "ax"], // 4
["pop", "bx"], // 5
["arr_push"], // 6
["inc"], // 7
["push", "bx"], // 8
["push", "ax"], // 9
["ld", "bx", 100],// 10
["jl", 4], // 11
["pop", "bx"], // 12
["pop", "ax"], // 13
["ret"]
]
var vm = new VM()
return vm.run(codes)
}
var arr = make_a_100_len_array_without_fucking_loop()
當然,還是沒有用循環。
寫了這麼多,沒有功勞也有苦勞啊,快點贊T_T
Array 的不少方法會跳過 undefined 確實是個著名的坑……
直接 map(just copy and paste to try)"".split("").map(function (v, i) { return i; });
Array(100).fill("naive").map(function (v, i) { return i; });
function* angry(i) {
yield i;
if (i &< 99) { yield* angry(i + 1); }
};
Array.from(angry(0));
(function wallace (i) { return (i &< 0) ? [] : wallace(i - 1).concat(i); })(99);
尾遞歸
(function mistake (i, acc) { return (i &< 100) ? mistake(i + 1, acc.concat(i)) : acc; })(0, []);
(function (excited) {
return function (f) {
return f(f);
}(function (f) {
return excited(function (x) { return (f(f))(x); });
});
})(function (excited) {
return function(i) {
return (i &< 0) ? [] : excited(i - 1).concat(i);
}
})(99);
這麼多人贊的嗎~其實巧妙的方法不是沒有。
class array { public: int operator[](size_t index) {return index;
} }; 還可以做得更騷,但手機碼字就懶得擼了(並不是因為買不起電腦啊!是因為睡前才刷的知乎)//////以下是原答案//////告訴你標準答案。手機碼字…將就著看吧…int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99};如果打表的成本低,那就打表。占坑混眼熟:
Object.keys(new Int8Array(100)).map(Number);
setTimeout 派系
var i = 0;
var a = [];
var timer = setInterval(function () {
a[i] = i++;
if (i &>= 100) {
clearInterval(timer);
console.log(a);
}
}, 1);
var a = [];
var i = 0;
function step(timestamp) {
if (i &< 100) {
a[i] = i++;
requestAnimationFrame(step);
} else {
console.log(a);
}
}
requestAnimationFrame(step);
" ".repeat(100).split("").map(Object.call, Number); // only chrome
document.body.innerHTML.substr(0, 100).split("").map(Object.call, Number);
Object.keys(String(Array(101)));
const _f = (n, l) =&> n &<= 0 ? l : _f(n-1, [n].concat(l));
const f = (n) =&> _f(n, []);
f(10) // =&> [1,2,3,4,5,6,7,8,9,10]
用eval來模擬goto,強行不算遞歸!
var target = [];
var command = `
if (target.length &< 100) {
target.push(target.length);
eval(command);
}`;
-&> eval(command);
-&> target
&<- [0, 1 ...99]
@kmxz 的第一個方法 回復不可以傳圖真相
Array.apply(null, {length: 100}).map(Number.call, Number)
Array.apply(null, {length: 100}).map(Object.call, Number)
補充下:
主要是利用一個Number.call(undefined, index, array)這樣一個思想,後面一個Number是為了在map中綁定需要的對象不用循環用遞歸唄你用foreach不還是loop嗎?
並沒有說明語言啊……不過一般來說給數組中所有元素賦值無外乎遍歷和遞歸,既然不用遍歷(考慮到各種容器底層實現也是遍歷居多),那麼用遞歸就好了。
int assign(int arr[],int idx){
return (idx&<0)?idx:(arr[idx]=assign(arr,idx-1)+1);
}
來答一下為什麼對於`new Array(n)`創建的數組用`map`方法無效,有人說是跳過undefined,有人說跳過空位
[ECMAScript-262 5.1](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.19)中對Array.prototype.map(callbackfn [, thisArg ])方法的描述有一句是:
&>`callbackfn` is called only for elements of the array which actually exist; it is not called for missing elements of the array.在`map`方法的運算步驟定義中也有一句:8. Repeat, while k &< len
a. Let Pk be ToString(k). b. Let kPresent be the result of calling the [[HasProperty]] internal method of O with argument Pk. c. If kPresent is true, then ...
在為數組中每個元素執行`callbackfn `之前,會先判斷這個元素是否在數組中實際存在(actually exist),判斷的方法就是調用內部方法[[HasProperty]]。
也可以使用Object.prototype.hasOwnProperty寫一段代碼說明:
var arr = [undefined, undefined];
arr.hasOwnProperty(0); // true
arr.hasOwnProperty(1); // true
arr.hasOwnProperty(2); // false
var arr2 = new Array(2);
arr2.hasOwnProperty(0); // false
arr2.hasOwnProperty(1); // false
可以看到通過`new Array(2)`創建的數組實際是不存在元素的,所以`map`方法中的`callbackfn`不會執行
不是說知乎回答支持markdown的么,我記錯了還是用錯了?有循環為啥不用?
用遞歸?這屬於沒事找事。
如果是我的話,我就回答,用循環,並且用 generator ,來咬我啊。如果 js 有 list comprehension 就更好了。我能封裝嗎?int GetTheValueOfAnElementByIndexFromAnArrayInWhichTheValueOfAnyElementIsEqualToItsIndex(int index) { return index;}
這道題TM找抽啊,到底要表達什麼意思?對於不同的語言有不同的解決方法:1、C/C++:可以直接malloc一片內存區域,然後直接給這片內存刷默認值(大概需要用到宏),然後把這片內存的指針直接扔給數組(內存管理這方面還是C/C++的夠直接);2、面向對象語言(Java、C#之類):TM不用loop循環可以用對象嵌套應用、再不濟也可以用遞歸啊;3、腳本語言(Python之類):老子不用loop循環那就是找腳本語言類庫里自帶的那些偏門的特性咯?TM我還知道茴香豆的四種寫法,你為啥不考這個?
Object.keys(new Int8Array(100))
我來玩一玩首先是Array.map
new Array(101).join("1").split("").map(function(v,i){return i})
當然forEach也行
p=new Array(101).join("1").split("")
p.forEach(function(v,i,a){a[i]=i})
console.log(p)
把合了再分改成fill也行
new Array(100).fill("").map(function(v,i){return i})
遞歸也行
(function f(i){if(i==0){return []};a=f(i-1);a.push(i-1);return a})(100)
對了還有Array.reduce
new Array(100).fill("").reduce(function(l,n,i,a){l.push(i);return l},[])
以及Array.reduceRight
new Array(100).fill("").reduceRight(function(l,n,i,a){l.push(99-i);return l},[])
ES6的話可以用Array.keys
[...new Array(100).keys()]
(估計是最短的了)
還有String.repeat" ".repeat(100).split("").map((v,i)=&>i)
還可以這樣
(f=(i)=&>i==0?[]:[...f(i-1),i])(99)
還有什麼想起來再寫
--
出題人路過...因為是校招的題目, 不會考太深的東西,
這裡其實就是想考慮下解題思路而已, 然後看看對 ES5/ES6 的一些方法是否有了解.
--我去尾遞歸不算loop啊!長見識。。。。
推薦閱讀:
※菜鳥想學計算機要從哪方面開始入手?
※足球經理《Football Manager》的比賽模擬原理是什麼?
※如何玩轉github?
※GitHub 上有些什麼好玩的項目?
※C語言中既然" "與空格『 』是不一樣的,那為什麼在字元串問題中,scanf中還不能讀入空格?
TAG:JavaScript | 編程 |