Giter VIP home page Giter VIP logo

Comments (53)

HuangQiii avatar HuangQiii commented on May 2, 2024 29

@sulingLiang 扁平化不改变原数据啊,你的结果也显示了,string型的变成了数字都

from blog.

Chan-Chun avatar Chan-Chun commented on May 2, 2024 12

最近ES10标准已经支持扁平化了!Array.flat(),以后也不用写这样的方法啦!
https://pawelgrzybek.com/whats-new-in-ecmascript-2019/#array-prototype-flat-array-prototype-flatmap-by-brian-terlson-michael-ficarra-and-mathias-bynens

from blog.

thereisnowinter avatar thereisnowinter commented on May 2, 2024 9

数组扁平化还可以这么写,不过初学者理解不了。

flatten = Function.apply.bind([].concat, [])

from blog.

mqyqingfeng avatar mqyqingfeng commented on May 2, 2024 6

@thereisnowinter 666~ 为你打 call~

稍微解释一下:

Function.apply.bind([].concat, [])

// 相当于

function(arg) {
  return Function.apply.call([].concat, [], arg)
}

// 相当于

function(arg) {
  return [].concat.apply([], arg)
}

// 相当于
// 这里错了
function(arg) {
   return [].concat(arg)
}

// 应该是

function(arg) {
   return [].concat(...arg)
}

from blog.

liuestc avatar liuestc commented on May 2, 2024 5
function flatten(input) {
  const stack = [...input];
  const res = [];
  while (stack.length) {
    // 使用 pop 从 stack 中取出并移除值
    const next = stack.pop();
    if (Array.isArray(next)) {
      // 使用 push 送回内层数组中的元素,不会改动原始输入 original input
      stack.push(...next);
    } else {
      res.push(next);
    }
  }
  // 使用 reverse 恢复原数组的顺序
  return res.reverse();
}

leecode上看到的*操作,感觉这个效率应该很高

from blog.

sulingLiang avatar sulingLiang commented on May 2, 2024 4

image
为什么“如果数组是 [1, '1', 2, '2'] 的话,这种方法就会产生错误的结果。”,可以解释一下吗?因为我运行了,是没问题的

from blog.

nitta-honoka avatar nitta-honoka commented on May 2, 2024 4

@xiaolb
push 会改变原数组,方法无返回值
concat 不会改变原数组,而是返回一个新数组,所以你需要这么写 result = result.concat(arr[i])

let a = [1, 2]
let b = [1, 2]
let c = []
c = a.push(3) // a: [1, 2, 3], c: undefined
c = b.concat(3) // b: [1, 2], c: [1, 2, 3]

from blog.

btea avatar btea commented on May 2, 2024 3

@nitta-honoka push 会改变原数组,也有返回值,返回值为数组push成功之后的长度。所以,c = a.push(3),c的值为3

from blog.

NameWjp avatar NameWjp commented on May 2, 2024 3

关于 flatten = Function.apply.bind([].concat, [])的理解,想了半天总算理解了。。。
首先是bind函数改变了this指向,而apply函数内部正是通过this去拿的执行的函数(参考博主前面call和apply的实现,一开始不理解就在这。。),然后传递了了[]参数,故现在flatten函数实际执行的是[].concat,this指向是[],还接受一个数组(apply的第二个参数)。

from blog.

Tan90Qian avatar Tan90Qian commented on May 2, 2024 1

@mqyqingfeng 看到dalao用concat和扩展运算符的时候愣了一下,几乎完全这个方法的印象,甚至还是去查了文档才知道如果要进行 concat() 操作的参数是数组,那么添加的是数组中的元素,而不是数组。这一点的。。。dalao你除了面试、写这些博客时候,日常开发中哪里会用到concat么?我之前半年似乎这个方法连5次都没用到

from blog.

mqyqingfeng avatar mqyqingfeng commented on May 2, 2024 1

@Tan90Qian 关于这两个问题:

  1. 不需要 return function 吧?
var flatten = Function.apply.bind([].concat, [])

// 相当于

var flatten = function(arg) {
  return Function.apply.call([].concat, [], arg)
}

正好就是对应的,不需要 return function 呀

  1. 嗯……也不需要吧,arg 本身就会传入一个数组,concat 也支持直接传入一个数组,不需要展开呀

from blog.

bosens-China avatar bosens-China commented on May 2, 2024 1
_.difference([1, 2, 3, 4, 5], [5, 2, 10], [4], 3);
=> [1, 3]

这个示例错误,正确的是

_.difference([1, 2, 3, 4, 5], [5, 2, 10], [4], 3);
=> [1, 3, 10]

from blog.

FrontToEnd avatar FrontToEnd commented on May 2, 2024

日常观光+学习

from blog.

kankk avatar kankk commented on May 2, 2024

学习了

from blog.

xiaobinwu avatar xiaobinwu commented on May 2, 2024

学习了,之后应该可以用到

from blog.

mqyqingfeng avatar mqyqingfeng commented on May 2, 2024

@HuangQiii 感谢回答~ (๑•̀ㅂ•́)و✧

from blog.

swpuLeo avatar swpuLeo commented on May 2, 2024

楼主你好,我发现你的 flatten() 有点问题:

先看 underscore 的:

const _ = require('underscore');
console.log(_.flatten([1, [2, [3, 4]], 5], false)); // [ 1, 2, 3, 4, 5 ]
console.log(_.flatten([1, [2, [3, 4]], 5], true)); // [ 1, 2, [ 3, 4 ], 5 ]

而楼主你的 flatten() 函数的表现如下:

/**
 * 数组扁平化
 * @param  {Array} input   要处理的数组
 * @param  {boolean} shallow 是否只扁平一层
 * @param  {boolean} strict  是否严格处理元素,下面有解释
 * @param  {Array} output  这是为了方便递归而传递的参数
 * 源码地址:https://github.com/jashkenas/underscore/blob/master/underscore.js#L528
 */
function flatten(input, shallow, strict, output) {

    // 递归使用的时候会用到output
    output = output || [];
    var idx = output.length;

    for (var i = 0, len = input.length; i < len; i++) {

        var value = input[i];
        // 如果是数组,就进行处理
        if (Array.isArray(value)) {
            // 如果是只扁平一层,遍历该数组,依此填入 output
            if (shallow) {
                var j = 0,
                    len = value.length;
                while (j < len) output[idx++] = value[j++];
            }
            // 如果是全部扁平就递归,传入已经处理的 output,递归中接着处理 output
            else {
                flatten(value, shallow, strict, output);
                idx = output.length;
            }
        }
        // 不是数组,根据 strict 的值判断是跳过不处理还是放入 output
        else if (!strict) {
            output[idx++] = value;
        }
    }

    return output;

}

console.log(flatten([1, [2, [3, 4]], 5], false, false)); // [ 1, 2, 3, 4, 5 ]
console.log(flatten([1, [2, [3, 4]], 5], true, false)); // [ 1, 2, [ 3, 4 ] ] 这里与 underscore 不一致

Debug 发现,楼主的 len 发生了变化,原来是楼主的 flatten() 函数中声明了两次 len 变量,将第二个 len 换个名字就行了。

var j = 0,
    len = value.length;  // 改为 length = value.length

from blog.

mqyqingfeng avatar mqyqingfeng commented on May 2, 2024

@swpuLeo 感谢指出哈 (๑•̀ㅂ•́)و✧ 确实有问题,我自己测试了一下,除了改成 var length = value.length 之外,while (j < len) output[idx++] = value[j++]; 这里的 len 也需要改成 length

from blog.

Tan90Qian avatar Tan90Qian commented on May 2, 2024

@thereisnowinter dalao 666~萌新学到了新的一手 apply和bind连用,同时绑定调用的方法和调用的主体,只留下一个参数的位置

from blog.

mqyqingfeng avatar mqyqingfeng commented on May 2, 2024

@Tan90Qian 处理数据或者需要返回一个新数组的时候,会用到 concat

from blog.

Tan90Qian avatar Tan90Qian commented on May 2, 2024

@mqyqingfeng 那基本就是在不能使用es6的情况下使用咯?否则“扩展操作符”+数组直接量的创建方式基本可以替代它的功能。然后就是类似数组展平这样,仅靠一个concat或者扩展操作符无法完成的功能。

PS:刚写的内容有2个问题,

  1. 因为是用了bind,所以“相当于”下的代码应该都是return function而不是直接function

  2. 由于第三个函数是从第二个函数应用了apply之后转过去的,所以转化出来的结果应该是将arg参数拆开后再传入的结果,也就是借助了eval或者rest操作符的版本

return function(arg) {
  return [].concat(...arg)
}

这也和博主大大在正文中的版本一致。

from blog.

Tan90Qian avatar Tan90Qian commented on May 2, 2024

@mqyqingfeng 第一条是我弄错了。不过第二条,确实是需要展开的,因为MDN对concat方法的描述:如果要进行 concat() 操作的参数是数组,那么添加的是数组中的元素,而不是数组,因此

[].concat([1,[2,[3,4]]])  // [1,[2,[3,4]]]
[].concat(...[1,[2,[3,4]]])
// 相当于
[].concat(1,[2,[3,4]]) // [1,2,[3,4]]

from blog.

mqyqingfeng avatar mqyqingfeng commented on May 2, 2024

@Tan90Qian 啊,是的,感谢指出~

from blog.

Fiv5 avatar Fiv5 commented on May 2, 2024

from blog.

Fiv5 avatar Fiv5 commented on May 2, 2024

from blog.

Latube avatar Latube commented on May 2, 2024

from blog.

mqyqingfeng avatar mqyqingfeng commented on May 2, 2024

@Fiv5 感谢告知~ 我并不知道这件事情,请教大家这种情况该怎么处理呢?

from blog.

delayk avatar delayk commented on May 2, 2024

@mqyqingfeng 微信公众号文章的话直接投诉就可以吧,有一个“未经授权的文章”选项

from blog.

huyong007 avatar huyong007 commented on May 2, 2024

/* 在javascript权威指南的第六版,p159*/
var objects=[{x:1,a:1},{y:2,a:2},{z:3,a:3}];
var leftunion=objects.reduce(union);//{x:1,y:2,z:3,a:1}
var rightunion=objects.reduceRight(union);//{x:1,y:2,z:3,a:3}
/书中p130页和p31页关于union和extend的设计是这样的/
function extend(o,p){
for(prop in p){
o[prop]=p[prop];
}
return o;
}

function union(o,p){return extend(extend({},o),p);}
/* 我的出来的结果和书中的出来的leftunion和rightunion的值正好是相反的,
书上也讲到,union()函数在碰到两个对象有同名属性时,使用第一个参数的属性值,
按照这个说法确实和结果相符,但是验证结果是他给出的union函数使用的extend()
使用第二个参数作为的属性值进行合并的,亲能帮我看看是我哪里错了吗?万分感谢,
我先去star一下您的项目啦 */

from blog.

huyong007 avatar huyong007 commented on May 2, 2024

楼主您的设计中第一个使用for循环的设计中我在实验这样一个 var arr = [1, [2, [[9, 0], 3, [2, 3]]]];结果给出的并不符合语气,我认为应该是您在设计for循环这个函数的时候外层的i被第二次出现的数组中的初始化给重置了,如果我们把for循环中的var改为let整个就没有任何问题了。

from blog.

xiaolb avatar xiaolb commented on May 2, 2024

楼主,有一个小疑问,就是方法1中将push变成concat为什么就得不到想要的结果了
// 方法 1
var arr = [1, [2, [3, 4]]];

function flatten(arr) {
var result = [];
for (var i = 0, len = arr.length; i < len; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]))
}
else {
result.concat(arr[i])
}
}
return result;
}

console.log(flatten(arr))

from blog.

xiaolb avatar xiaolb commented on May 2, 2024

@nitta-honoka 感谢!

from blog.

inottn avatar inottn commented on May 2, 2024

@huyong007

书也是会出错的。下面是原书的勘误:

I found incorrect result at comment.

Now
var objects = [{x:1,a:1}, {y:2,a:2}, {z:3,a:3}];
var leftunion = objects.reduce(union); // {x:1, y:2, z:3, a:1}
var rightunion = objects.reduceRight(union); // {x:1, y:2, z:3, a:3}

I think result
var objects = [{x:1,a:1}, {y:2,a:2}, {z:3,a:3}];
var leftunion = objects.reduce(union); // {x:1, y:2, z:3, a:3}
var rightunion = objects.reduceRight(union); // {x:1, y:2, z:3, a:1}

adjusting point
// {x:1, y:2, z:3, a:1} -> // {x:1, y:2, z:3, a:3}
// {x:1, y:2, z:3, a:3} -> // {x:1, y:2, z:3, a:1}

Note from the Author or Editor:
Change code to read:

var leftunion = objects.reduce(union); // {x:1, y:2, z:3, a:3}
var rightunion = objects.reduceRight(union); // {x:1, y:2, z:3, a:1}

from blog.

fairyly avatar fairyly commented on May 2, 2024

es 6 中已经提供数组扁平化方法使用 flat();
不过知道怎么实现的 还是很有帮助的

参考:

from blog.

zjp6049 avatar zjp6049 commented on May 2, 2024

额 几个月前看没觉得什么 最近突然遇到扁平化才知道不用递归写出扁平化牛P了哈

from blog.

goSunadeod avatar goSunadeod commented on May 2, 2024

// 如果是全部扁平就递归,传入已经处理的 output,递归中接着处理 output else { flatten(value, shallow, strict, output); idx = output.length; }
这个idx重置 有作用吗。。。麻烦又大佬知道的能告知一下,谢谢

from blog.

JSluowen avatar JSluowen commented on May 2, 2024

感觉又进步一点点了

from blog.

tr2v avatar tr2v commented on May 2, 2024

// 如果是全部扁平就递归,传入已经处理的 output,递归中接着处理 output else { flatten(value, shallow, strict, output); idx = output.length; }
这个idx重置 有作用吗。。。麻烦又大佬知道的能告知一下,谢谢

递归数组后,output会变啊,不变idx,后面再插入数组项不就变成替换以后的了吗,我不明白的是这里怎么不直接用push呢

from blog.

goSunadeod avatar goSunadeod commented on May 2, 2024

// 如果是全部扁平就递归,传入已经处理的 output,递归中接着处理 output else { flatten(value, shallow, strict, output); idx = output.length; }
这个idx重置 有作用吗。。。麻烦又大佬知道的能告知一下,谢谢

递归数组后,output会变啊,不变idx,后面再插入数组项不就变成替换以后的了吗,我不明白的是这里怎么不直接用push呢

递归时output会变,但不是函数里面会重新 定义var idx = output.length 吗 这和 递归函数之后的那句代码idx = output.length; 并没有关系啊

from blog.

tr2v avatar tr2v commented on May 2, 2024

递归时output会变,但不是函数里面会重新 定义var idx = output.length 吗 这和 递归函数之后的那句代码idx = output.length; 并没有关系啊

函数内的idx是最新的没错,但是外部的还是原来的,递归结束后肯定要再获取一下

from blog.

wbc0301 avatar wbc0301 commented on May 2, 2024

console.log([].concat(...arr)) 这里用到的是函数的 rest 参数,大佬说成是数组的扩展运算符了

from blog.

rongda avatar rongda commented on May 2, 2024
var arr1 = [1, 2, [3, 4]];
arr1.flat(Infinity)

from blog.

guanxc9876 avatar guanxc9876 commented on May 2, 2024

output[idx++] = value[j++];这种出来的数组下标是不规律的,为啥不直接用push

from blog.

Guard-233 avatar Guard-233 commented on May 2, 2024
const flatten = (arr, shallow, strict) => {
  return arr.reduce((now, next) => {
    if (!shallow) {
      next = Array.isArray(next) ? flatten(next, shallow, strict) : next
    }
    if (strict && !Array.isArray(next)) {
      next = []
    }
    return now.concat(next)
  }, [])
}

稍微简化了一下

from blog.

bikedawuwang avatar bikedawuwang commented on May 2, 2024

学习了

from blog.

buquan avatar buquan commented on May 2, 2024

扁平化

数组的扁平化,就是将一个嵌套多层的数组 array (嵌套可以是任何层数)转换为只有一层的数组。

举个例子,假设有个名为 flatten 的函数可以做到数组扁平化,效果就会如下:

var arr = [1, [2, [3, 4]]];
console.log(flatten(arr)) // [1, 2, 3, 4]

知道了效果是什么样的了,我们可以去尝试着写这个 flatten 函数了

递归

我们最一开始能想到的莫过于循环数组元素,如果还是一个数组,就递归调用该方法:

// 方法 1
var arr = [1, [2, [3, 4]]];

function flatten(arr) {
    var result = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        if (Array.isArray(arr[i])) {
            result = result.concat(flatten(arr[i]))
        }
        else {
            result.push(arr[i])
        }
    }
    return result;
}


console.log(flatten(arr))

toString

如果数组的元素都是数字,那么我们可以考虑使用 toString 方法,因为:

[1, [2, [3, 4]]].toString() // "1,2,3,4"

调用 toString 方法,返回了一个逗号分隔的扁平的字符串,这时候我们再 split,然后转成数字不就可以实现扁平化了吗?

// 方法2
var arr = [1, [2, [3, 4]]];

function flatten(arr) {
    return arr.toString().split(',').map(function(item){
        return +item
    })
}

console.log(flatten(arr))

然而这种方法使用的场景却非常有限,如果数组是 [1, '1', 2, '2'] 的话,这种方法就会产生错误的结果。

reduce

既然是对数组进行处理,最终返回一个值,我们就可以考虑使用 reduce 来简化代码:

// 方法3
var arr = [1, [2, [3, 4]]];

function flatten(arr) {
    return arr.reduce(function(prev, next){
        return prev.concat(Array.isArray(next) ? flatten(next) : next)
    }, [])
}

console.log(flatten(arr))

...

ES6 增加了扩展运算符,用于取出参数对象的所有可遍历属性,拷贝到当前对象之中:

var arr = [1, [2, [3, 4]]];
console.log([].concat(...arr)); // [1, 2, [3, 4]]

我们用这种方法只可以扁平一层,但是顺着这个方法一直思考,我们可以写出这样的方法:

// 方法4
var arr = [1, [2, [3, 4]]];

function flatten(arr) {

    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr);
    }

    return arr;
}

console.log(flatten(arr))

undercore

那么如何写一个抽象的扁平函数,来方便我们的开发呢,所有又到了我们抄袭 underscore 的时候了~

在这里直接给出源码和注释,但是要注意,这里的 flatten 函数并不是最终的 _.flatten,为了方便多个 API 进行调用,这里对扁平进行了更多的配置。

/**
 * 数组扁平化
 * @param  {Array} input   要处理的数组
 * @param  {boolean} shallow 是否只扁平一层
 * @param  {boolean} strict  是否严格处理元素,下面有解释
 * @param  {Array} output  这是为了方便递归而传递的参数
 * 源码地址:https://github.com/jashkenas/underscore/blob/master/underscore.js#L528
 */
function flatten(input, shallow, strict, output) {

    // 递归使用的时候会用到output
    output = output || [];
    var idx = output.length;

    for (var i = 0, len = input.length; i < len; i++) {

        var value = input[i];
        // 如果是数组,就进行处理
        if (Array.isArray(value)) {
            // 如果是只扁平一层,遍历该数组,依此填入 output
            if (shallow) {
                var j = 0, length = value.length;
                while (j < length) output[idx++] = value[j++];
            }
            // 如果是全部扁平就递归,传入已经处理的 output,递归中接着处理 output
            else {
                flatten(value, shallow, strict, output);
                idx = output.length;
            }
        }
        // 不是数组,根据 strict 的值判断是跳过不处理还是放入 output
        else if (!strict){
            output[idx++] = value;
        }
    }

    return output;

}

解释下 strict,在代码里我们可以看出,当遍历数组元素时,如果元素不是数组,就会对 strict 取反的结果进行判断,如果设置 strict 为 true,就会跳过不进行任何处理,这意味着可以过滤非数组的元素,举个例子:

var arr = [1, 2, [3, 4]];
console.log(flatten(arr, true, true)); // [3, 4]

那么设置 strict 到底有什么用呢?不急,我们先看下 shallow 和 strct 各种值对应的结果:

  • shallow true + strict false :正常扁平一层
  • shallow false + strict false :正常扁平所有层
  • shallow true + strict true :去掉非数组元素
  • shallow false + strict true : 返回一个[]

我们看看 underscore 中哪些方法调用了 flatten 这个基本函数:

_.flatten

首先就是 _.flatten:

_.flatten = function(array, shallow) {
    return flatten(array, shallow, false);
};

在正常的扁平中,我们并不需要去掉非数组元素。

_.union

接下来是 _.union:

该函数传入多个数组,然后返回传入的数组的并集,

举个例子:

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

如果传入的参数并不是数组,就会将该参数跳过:

_.union([1, 2, 3], [101, 2, 1, 10], 4, 5);
=> [1, 2, 3, 101, 10]

为了实现这个效果,我们可以将传入的所有数组扁平化,然后去重,因为只能传入数组,这时候我们直接设置 strict 为 true,就可以跳过传入的非数组的元素。

// 关于 unique 可以查看《JavaScript专题之数组去重》[](https://github.com/mqyqingfeng/Blog/issues/27)
function unique(array) {
   return Array.from(new Set(array));
}

_.union = function() {
    return unique(flatten(arguments, true, true));
}

_.difference

是不是感觉折腾 strict 有点用处了,我们再看一个 _.difference:

语法为:

_.difference(array, *others)

效果是取出来自 array 数组,并且不存在于多个 other 数组的元素。跟 _.union 一样,都会排除掉不是数组的元素。

举个例子:

_.difference([1, 2, 3, 4, 5], [5, 2, 10], [4], 3);
=> [1, 3]

实现方法也很简单,扁平 others 的数组,筛选出 array 中不在扁平化数组中的值:

function difference(array, ...rest) {

    rest = flatten(rest, true, true);

    return array.filter(function(item){
        return rest.indexOf(item) === -1;
    })
}

注意,以上实现的细节并不是完全按照 underscore,具体细节的实现感兴趣可以查看源码

专题系列

JavaScript专题系列目录地址:https://github.com/mqyqingfeng/Blog。

JavaScript专题系列预计写二十篇左右,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里、递归、乱序、排序等,特点是研(chao)究(xi) underscore 和 jQuery 的实现方式。

如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。

学习了

+1

from blog.

Junezm avatar Junezm commented on May 2, 2024

解构运算原理来打平数组

function* flatten(arr) {
    for (const item of arr) {
        if(Array.isArray(item)){
            yield* flatten(item)
        } else {
            yield item
        }
    }
}

var arr = [1, 2, [3, 4, [5, 6]]];
const flattened = [...flatten(arr)];

from blog.

anjina avatar anjina commented on May 2, 2024

可以修改原数组的扁平化

// splice 修改原数组
function flattern_v3(arr, depth) {
  if(depth < 1) return arr;

  let i, len;
  for(i=0, len=arr.length; i < len; i++) {
    const item = arr[i];

    if(Array.isArray(item) && depth) {
      arr.splice(i, 1, ...item);
      len += item.length - 1;
      depth--;
    }
  }
}

from blog.

banli17 avatar banli17 commented on May 2, 2024

@bosens-China
[1,3],这个是在 arr 去掉 ...rest 里有的

from blog.

chloeeee72 avatar chloeeee72 commented on May 2, 2024

可以直接使用数组的.flat()方法,在括号内传入提取嵌套数组的结构深度就行了,MDN:Array.prototype.flat()

from blog.

hotYan avatar hotYan commented on May 2, 2024

使用 Generator 函数实现数组扁平化:

function* flat(arr){
    if(Array.isArray(arr)){
        for(const item of arr){
            yield* flat(item)
        }
    }else{
       yield arr
    }
}
// 测试
let flatted = [ ...flat([1,2,[3,4,[5,6]]]) ]
console.log(flatted) // [1,2,3,4,5,6]

from blog.

RowlingJoe avatar RowlingJoe commented on May 2, 2024

arr.join(',').split(',')

from blog.

rongda avatar rongda commented on May 2, 2024

from blog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.