wangjiong's blog

everyday is new day


  • 首页

  • 归档

  • 分类

  • 标签

js数据结构与算法-排序

发表于 2018-03-17 | 分类于 js
1
2
3
4
5
function swap(arr, a, b) {
var temp = arr[a]
arr[a] = arr[b]
arr[b] = temp
}

冒泡排序:特点相邻元素交换位置,j循环每遍历一轮,冒泡一个最大值到顶部
时间复杂度:O(n*n)
空间复杂度:O(1)
稳定性:稳定

1
2
3
4
5
6
7
8
9
10
function buddleSort(arr) {
var len = arr.length;
for(var i = 0; i < len; i++) {
for (var j = 0; j < len - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j +1 )
}
}
}
}

选择排序:j循环选择最小的与i交换
时间复杂度:O(n*n)
空间复杂度:O(1)
稳定性:不稳定

1
2
3
4
5
6
7
8
9
10
11
12
function selectSort(arr) {
var len = arr.length;
for(var i = 0; i < len; i++) {
var minIndex = i;
for (var j = i + 1; j < len; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j
}
}
swap(arr, i, minIndex)
}
}

插入排序:将待排序依次插入已排序序列的合适位置
时间复杂度:O(n*n)
空间复杂度:O(1)
稳定性:稳定

1
2
3
4
5
6
7
8
9
10
11
function insertSort(arr) {
var len = arr.length;
for(var i = 0; i < len; i++) {
var minIndex = i;
while(j = i && arr[j] < arr[j - 1]) {
swap(arr, j, j - 1)
--j
}
}
}

希尔排序:插入排序的改善,定义一个间隔序列
时间复杂度:O(nlog2n)
空间复杂度:O(1)
稳定性:不稳定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//间隔序列,分别以间隔序列里面的间隔进行插入排序
var gaps = [5, 3, 1]
function shellSort(arr) {
var len = arr.length;
var gapsLen = gaps.length
for (var g = 0; g < gapsLen; g++) {
var gap = gaps[g]
for (var i = gap; i < len; i++) {
var temp = arr[i];
for (var j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}

快速排序:递归将数据依次分为包含较小元素和较大元素不同子序列,分治法
时间复杂度:O(nlog2n)
空间复杂度:O(nlog2n)
稳定性:不稳定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function quickSort(arr) {
var minArr = []
var maxArr = []
var pri = arr[0]
var len = arr.length
for (var i = 0; i < len; i++) {
if (arr[i] < pri) {
minArr.push(arr[i])
} else {
maxArr.push(arr[i])
}
}
return quickSort(minArr).concat(pri, quickSort(maxArr))
}

归并排序:把一系列排好序的子序列合并成一个大的完整有序序列,自顶向下(递归,深度太深,一般不用),自底向上(迭代)
时间复杂度:O(nlog2n)
空间复杂度:O(n)
稳定性:稳定

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
//递归实现
function merge(left, right) {
var tmp = [];
while (left.length && right.length) {
if (left[0] < right[0])
tmp.push(left.shift());
else
tmp.push(right.shift());
}
return tmp.concat(left, right);
}
function mergeSort(a) {
if (a.length === 1)
return a;
var mid = ~~(a.length / 2)
, left = a.slice(0, mid)
, right = a.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
// 迭代实现
function merge(left, right) {
var result = [];
while (left.length && right.length) {
if (left[0] < right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
return result.concat(left, right);
}
function mergeSort(arr) {
if (arr.length === 1)
return arr;
var work = [];
for (var i = 0, len = arr.length; i < len; i++) {
work.push([arr[i]]);
}
work.push([]);
for (var lim = len; lim > 1; lim = ~~((lim + 1) / 2)) {
for (var j = 0, k = 0; k < lim; j++, k += 2) {
work[j] = merge(work[k], work[k + 1]);
}
work[j] = [];
}
return work[0];
}

d3-timer

发表于 2017-10-19 | 分类于 js

安排一个定时器

1
2
3
4
5
6
var taskHead,
taskTail
var t = d3.timer(function(elapsed) {
console.log(elapsed);
if (elapsed > 200) t.stop();
}, 500);

调用timer函数,内部生成一个Timer对象,并调用restart()函数,内部sleep(),会调用setFrame()

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
100
101
102
103
104
105
106
107
108
109
110
var frame = 0, // is an animation frame pending?
timeout = 0, // is a timeout pending?
interval = 0, // are any timers active?
pokeDelay = 1000, // how frequently we check for clock skew
taskHead,
taskTail,
clockLast = 0,
clockNow = 0,
clockSkew = 0,
clock = typeof performance === "object" && performance.now ? performance : Date,
setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
export function now() {
return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
}
function clearNow() {
clockNow = 0;
}
export function Timer() {
this._call =
this._time =
this._next = null;
}
Timer.prototype = timer.prototype = {
constructor: Timer,
restart: function(callback, delay, time) {
if (typeof callback !== "function") throw new TypeError("callback is not a function");
time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
if (!this._next && taskTail !== this) {
if (taskTail) taskTail._next = this;
else taskHead = this;
taskTail = this;
}
this._call = callback;
this._time = time;
sleep();
},
stop: function() {
if (this._call) {
this._call = null;
this._time = Infinity;
sleep();
}
}
};
export function timer(callback, delay, time) {
var t = new Timer;
t.restart(callback, delay, time);
return t;
}
export function timerFlush() {
now(); // Get the current time, if not already set.
++frame; // Pretend we’ve set an alarm, if we haven’t already.
var t = taskHead, e;
while (t) {
if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
t = t._next;
}
--frame;
}
function wake() {
clockNow = (clockLast = clock.now()) + clockSkew;
frame = timeout = 0;
try {
timerFlush();
} finally {
frame = 0;
nap();
clockNow = 0;
}
}
function poke() {
var now = clock.now(), delay = now - clockLast;
if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
}
function nap() {
var t0, t1 = taskHead, t2, time = Infinity;
while (t1) {
if (t1._call) {
if (time > t1._time) time = t1._time;
t0 = t1, t1 = t1._next;
} else {
t2 = t1._next, t1._next = null;
t1 = t0 ? t0._next = t2 : taskHead = t2;
}
}
taskTail = t0;
sleep(time);
}
function sleep(time) {
if (frame) return; // Soonest alarm already set, or will be.
if (timeout) timeout = clearTimeout(timeout);
var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
if (delay > 24) {
if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
if (interval) interval = clearInterval(interval);
} else {
if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
frame = 1, setFrame(wake);
}
}

d3.timeout(callback[, delay[, time]])
时间结束后回调

1
d3.timeout(() => {console.log('timeout')}, 2000)

1
2
3
4
5
6
7
8
9
10
11
import {Timer} from "./timer";
export default function(callback, delay, time) {
var t = new Timer;
delay = delay == null ? 0 : +delay;
t.restart(function(elapsed) {
t.stop();
callback(elapsed + delay);
}, delay, time);
return t;
}

d3.interval(callback[, delay[, time]])定时回调

1
d3.interval(() => {console.log('interval')}, 2000)

1
2
3
4
5
6
7
8
9
10
11
12
13
import {Timer, now} from "./timer";
export default function(callback, delay, time) {
var t = new Timer, total = delay;
if (delay == null) return t.restart(callback, delay, time), t;
delay = +delay, time = time == null ? now() : +time;
t.restart(function tick(elapsed) {
elapsed += total;
t.restart(tick, total += delay, time);
callback(elapsed);
}, delay, time);
return t;
}

d3-request

发表于 2017-10-19 | 分类于 js
1
2
3
d3.request("/path/to/resource") // 返回一个request对象
.header("Content-Type", "application/x-www-form-urlencoded") // 设置请求报头
.post("a=2&b=3", callback) // 发送请求

request请求

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import {map} from "d3-collection";
import {dispatch} from "d3-dispatch";
export default function(url, callback) {
var request,
event = dispatch("beforesend", "progress", "load", "error"),
mimeType,
headers = map(),
xhr = new XMLHttpRequest,
user = null,
password = null,
response,
responseType,
timeout = 0;
// If IE does not support CORS, use XDomainRequest.
if (typeof XDomainRequest !== "undefined"
&& !("withCredentials" in xhr)
&& /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
// 根据onreadystatechange,readyState 触发respond
"onload" in xhr
? xhr.onload = xhr.onerror = xhr.ontimeout = respond
: xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
function respond(o) {
var status = xhr.status, result;
if (!status && hasResponse(xhr)
|| status >= 200 && status < 300
|| status === 304) {
if (response) {
try {
result = response.call(request, xhr);
} catch (e) {
event.call("error", request, e);
return;
}
} else {
result = xhr;
}
event.call("load", request, result);
} else {
event.call("error", request, o);
}
}
xhr.onprogress = function(e) {
event.call("progress", request, e);
};
request = {
// 设置header
header: function(name, value) {
name = (name + "").toLowerCase();
if (arguments.length < 2) return headers.get(name);
if (value == null) headers.remove(name);
else headers.set(name, value + "");
return request;
},
// 设置mimeType
// If mimeType is non-null and no Accept header is set, a default is used.
mimeType: function(value) {
if (!arguments.length) return mimeType;
mimeType = value == null ? null : value + "";
return request;
},
// Specifies what type the response value should take;
// for instance, arraybuffer, blob, document, or text.
responseType: function(value) {
if (!arguments.length) return responseType;
responseType = value;
return request;
},
timeout: function(value) {
if (!arguments.length) return timeout;
timeout = +value;
return request;
},
user: function(value) {
return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
},
password: function(value) {
return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
},
// Specify how to convert the response content to a specific type;
// changes the callback value on "load" events.
response: function(value) {
response = value;
return request;
},
// Alias for send("GET", …).
get: function(data, callback) {
return request.send("GET", data, callback);
},
// Alias for send("POST", …).
post: function(data, callback) {
return request.send("POST", data, callback);
},
// If callback is non-null, it will be used for error and load events.
send: function(method, data, callback) {
xhr.open(method, url, true, user, password);
if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
if (responseType != null) xhr.responseType = responseType;
if (timeout > 0) xhr.timeout = timeout;
if (callback == null && typeof data === "function") callback = data, data = null;
if (callback != null && callback.length === 1) callback = fixCallback(callback);
if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
event.call("beforesend", request, xhr);
xhr.send(data == null ? null : data);
return request;
},
abort: function() {
xhr.abort();
return request;
},
on: function() {
var value = event.on.apply(event, arguments);
return value === event ? request : value;
}
};
if (callback != null) {
if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
return request.get(callback);
}
return request;
}
function fixCallback(callback) {
return function(error, xhr) {
callback(error == null ? xhr : null);
};
}
function hasResponse(xhr) {
var type = xhr.responseType;
return type && type !== "text"
? xhr.response // null on error
: xhr.responseText; // "" on error
}

请求不同类型封装

1
2
3
4
d3.text("/path/to/file.txt", function(error, text) {
if (error) throw error;
console.log(text); // Hello, world!
});

text.js

1
2
3
4
5
import type from "./type";
export default type("text/plain", function(xhr) {
return xhr.responseText;
});

type.js

1
2
3
4
5
6
7
8
9
10
11
12
import request from "./request";
export default function(defaultMimeType, response) {
return function(url, callback) {
var r = request(url).mimeType(defaultMimeType).response(response);
if (callback != null) {
if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
return r.get(callback);
}
return r;
};
}

d3-color

发表于 2017-10-19 | 分类于 js

d3-color支持多种颜色格式,rgb(red,green,blue),hsl(hue,saturation,lightness),lab,hcl,cubehelix。

1
2
3
4
5
6
7
8
d3.color('steelblue') // At{r: 70, g: 130, b: 180, opacity: 1}
d3.rgb('steelblue') // At{r: 70, g: 130, b: 180, opacity: 1}
d3.hsl('steelblue') // Rt{h: 207.27272727272728, s: 0.44, l: 0.4901960784313726, opacity: 1}
d3.lab('steelblue') // Dt{l: 52.46551718768575, a: -4.0774710123572255, b: -32.19186122981343, opacity: 1}
d3.hcl('steelblue') // Ht{h: 262.78126775909277, c: 32.44906314974561, l: 52.46551718768575, opacity: 1}
d3.cubehelix('steelblue') // Vt{h: 202.84837896488932, s: 0.6273147230777709, l: 0.460784355920337, opacity: 1}
d3.color('steelblue').toString() // "rgb(70, 130, 180)"

rgb,hsl,lab,hcl,cubehelix继承自color

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
export default function(constructor, factory, prototype) {
constructor.prototype = factory.prototype = prototype;
prototype.constructor = constructor;
}
// 返回parent.prototype的copy对象,该对象同时继承definition的属性和方法
export function extend(parent, definition) {
var prototype = Object.create(parent.prototype);
for (var key in definition) prototype[key] = definition[key];
return prototype;
}
export function Color() {}
export function rgb(r, g, b, opacity) {
return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
}
export function Rgb(r, g, b, opacity) {
this.r = +r;
this.g = +g;
this.b = +b;
this.opacity = +opacity;
}
define(Rgb, rgb, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
},
rgb: function() {
return this;
},
// 判断颜色是否有效
displayable: function() {
return (0 <= this.r && this.r <= 255)
&& (0 <= this.g && this.g <= 255)
&& (0 <= this.b && this.b <= 255)
&& (0 <= this.opacity && this.opacity <= 1);
},
toString: function() {
var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
return (a === 1 ? "rgb(" : "rgba(")
+ Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
+ Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
+ Math.max(0, Math.min(255, Math.round(this.b) || 0))
+ (a === 1 ? ")" : ", " + a + ")");
}
}));

d3-dispatch

发表于 2017-10-19 | 分类于 js

事件分发器的用法如下

1
2
3
4
5
6
7
8
9
10
// 创建事件分发器 传入参数 事件分发器type
var d = dispatch("start")
// 绑定事件
function startCallback() {console.log('startCallback')}
// type.name
d.on("start.call", startCallback)
// 触发事件
d.call("start");
//d.apply("start");
// {_:{start: [{name:call, value: startCallback}]}}

生成的事件分发器对象
{_:{start: [{name:call, value: startCallback}]}}
使用apply或call触发事件回调函数,遍历type数组内所有事件type名称,执行value.apply()或value.call(),value内存储对应的回调函数

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
var noop = {value: function() {}};
// 事件分发器工厂
function dispatch() {
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
_[t] = [];
}
return new Dispatch(_);
}
// 事件分发器构造函数
function Dispatch(_) {
this._ = _;
}
function parseTypenames(typenames, types) {
// 事件分发器类型字符串处理
// 去除开始结束空格,去除特殊字符
return typenames.trim().split(/^|\s+/).map(function(t) {
// type.name 拆分
var name = "", i = t.indexOf(".");
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
return {type: t, name: name};
});
}
Dispatch.prototype = dispatch.prototype = {
constructor: Dispatch,
on: function(typename, callback) {
var _ = this._,
T = parseTypenames(typename + "", _),
t,
i = -1,
n = T.length;
// If no callback was specified, return the callback of the given type and name.
if (arguments.length < 2) {
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
return;
}
// If a type was specified, set the callback for the given type and name.
// Otherwise, if a null callback was specified, remove callbacks of the given name.
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
while (++i < n) {
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
}
return this;
},
copy: function() {
// 复制_,生成新的dispatch对象
var copy = {}, _ = this._;
for (var t in _) copy[t] = _[t].slice();
return new Dispatch(copy);
},
call: function(type, that) {
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
// 遍历执行回调函数
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
},
apply: function(type, that, args) {
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
}
};
function get(type, name) {
for (var i = 0, n = type.length, c; i < n; ++i) {
if ((c = type[i]).name === name) {
return c.value;
}
}
}
function set(type, name, callback) {
for (var i = 0, n = type.length; i < n; ++i) {
if (type[i].name === name) {
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
break;
}
}
if (callback != null) type.push({name: name, value: callback});
return type;
}

d3-select

发表于 2017-10-18 | 分类于 js

lodash-hash实现

发表于 2017-10-16 | 分类于 js
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
const HASH_UNDEFINED = '__lodash_hash_undefined__'
class Hash {
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
constructor(entries) {
let index = -1
const length = entries == null ? 0 : entries.length
this.clear()
while (++index < length) {
const entry = entries[index]
this.set(entry[0], entry[1])
}
}
/**
* Removes all key-value entries from the hash.
*
* @memberOf Hash
*/
clear() {
this.__data__ = Object.create(null)
this.size = 0
}
/**
* Removes `key` and its value from the hash.
*
* @memberOf Hash
* @param {Object} hash The hash to modify.
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
delete(key) {
const result = this.has(key) && delete this.__data__[key]
this.size -= result ? 1 : 0
return result
}
/**
* Gets the hash value for `key`.
*
* @memberOf Hash
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
get(key) {
const data = this.__data__
const result = data[key]
return result === HASH_UNDEFINED ? undefined : result
}
/**
* Checks if a hash value for `key` exists.
*
* @memberOf Hash
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
has(key) {
const data = this.__data__
return data[key] !== undefined
}
/**
* Sets the hash `key` to `value`.
*
* @memberOf Hash
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the hash instance.
*/
set(key, value) {
const data = this.__data__
this.size += this.has(key) ? 0 : 1
data[key] = value === undefined ? HASH_UNDEFINED : value
return this
}
}

lodash-flattern实现

发表于 2017-10-16 | 分类于 js
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
// 减少一级数组嵌套
function flatten(array) {
const length = array == null ? 0 : array.length
return length ? baseFlatten(array, 1) : []
}
// 减少到一维
function flattenDeep(array) {
const length = array == null ? 0 : array.length
return length ? baseFlatten(array, INFINITY) : []
}
// 减少depth维
function flattenDepth(array, depth) {
const length = array == null ? 0 : array.length
if (!length) {
return []
}
depth = depth === undefined ? 1 : +depth
return baseFlatten(array, depth)
}
/**
* @private
* @param {Array} array 需要处理的数组
* @param {number} depth 需要减少的维度
* @param {boolean} [predicate=isFlattenable] 每个元素回调函数,判断是否一维,默认isFlattenable
* @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
* @param {Array} [result=[]] 初始结果值
* @returns {Array} 返回结果
*/
function baseFlatten(array, depth, predicate, isStrict, result) {
predicate || (predicate = isFlattenable)
result || (result = [])
if (array == null) {
return result
}
for (const value of array) {
if (depth > 0 && predicate(value)) {
if (depth > 1) {
// Recursively flatten arrays (susceptible to call stack limits).
baseFlatten(value, depth - 1, predicate, isStrict, result)
console.log(value)
} else {
result.push(...value)
}
} else if (!isStrict) {
result[result.length] = value
}
}
return result
}

nodejs反向代理

发表于 2017-10-13 | 分类于 nodejs

正向代理代理客户端,反向代理代理服务器。
使用nodejs实现简单的反向代理需要
1、创建一个http服务
2、服务接收到客户端请求后,去请求目的url
3、获取请求结果,返回给客户端

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
var http = require('http');
var https = require('https');
var path = require('path');
console.log('run')
// Create HTTP Server
http.createServer(function(req, res) {
var uri = 'https://github.com/' + req.url;
var file = req.url.replace(/\?.*/ig, '');
var ext = path.extname(file);
var type = getContentType(ext);
res.writeHead(200, {
'Content-Type': type
});
https.get(uri, function(response) {
response.addListener('data', function(chunk)
{
res.write(chunk, 'binary');
});
response.addListener('end', function()
{
res.end();
});
});
}).listen(3000);
// Get content-type
var getContentType = function(ext) {
var contentType = '';
switch (ext) {
case "":
contentType = "text/html";
break;
case ".html":
contentType = "text/html";
break;
case ".js":
contentType = "text/javascriptss";
break;
case ".css":
contentType = "text/css";
break;
case ".gif":
contentType = "image/gif";
break;
case ".jpg":
contentType = "image/jpeg";
break;
case ".png":
contentType = "image/png";
break;
case ".ico":
contentType = "image/icon";
break;
default:
contentType = "application/octet-stream";
}
return contentType;
};

使用synaptic搭建XOR感知器

发表于 2017-07-11

synaptic大约是现在最活跃的js神经网络库,github地址

123
Wang Jiong

Wang Jiong

happy coding

25 日志
4 分类
10 标签
© 2018 Wang Jiong
由 Hexo 强力驱动
主题 - NexT.Muse