Mather

We create our own demons.

使用 ES2015 处理数组

默认分类 0 评

Array.map()

使用 map 函数,把一个数据集合转换或映射成另一个数据集合。

取出数组所有元素中某个字段

const channels = [
    {"id": 4, "title": "文化", "platform": "app", "type": "channel", "ordering": 4},
    {"id": 1, "title": "推荐", "platform": "app", "type": "channel", "ordering": 1},
    {"id": 7, "title": "人物", "platform": "app", "type": "channel", "ordering": 5}
]

const mapped = channels.map(item => item.title)

console.log(mapped)

> Array ["文化", "推荐", "人物"]

callback 函数返回值组成一个数组,这里 ES6 箭头写法省略了 return

增删所有元素中的字段

const channels = [
    {"id": 4, "title": "文化", "platform": "app", "type": "channel", "ordering": 4},
    {"id": 1, "title": "推荐", "platform": "app", "type": "channel", "ordering": 1},
    {"id": 7, "title": "人物", "platform": "app", "type": "channel", "ordering": 5}
]

const mapped = channels.map(item => {
    const { platform, ordering, ...rest } = item 
    
    return {
        ...rest,
        author: '',
        link: `//www.adc.com/channel/${item.id}`
    }
    
})

console.log(mapped)

> Array [
    Object { id: 4, title: "文化", type: "channel", author: "", link: "//www.adc.com/channel/4" },
    Object { id: 1, title: "推荐", type: "channel", author: "", link: "//www.adc.com/channel/1" }, 
    Object { id: 7, title: "人物", type: "channel", author: "", link: "//www.adc.com/channel/7" }
]

配合扩展运算符、rest 参数、对象解构将需要的字段重新组合成新的数组。

Array.filter()

和 Map 一样,接受一个函数,函数内返回 布尔值 truefalse ,第二个参数作为函数内 this

过滤/筛选数组元素中适合的元素

const channels = [
    { "id": 4, "title": "文化", "platform": "pc",  "type": "channel", "ordering": 4},
    { "id": 1, "title": "推荐", "platform": "app", "type": "channel", "ordering": 1},
    { "id": 7, "title": "人物", "platform": "app", "type": "channel", "ordering": 5}
]

const filtered = channels.filter(item => { 
    return item.platform === 'pc' && item.type === 'channel'
})

console.log(filtered)

> Array [Object { id: 4, title: "文化", platform: "pc", type: "channel", ordering: 4 }]

可以在匿名函数中编写规则,匹配某个字段,筛选出你需要的元素。

Array.find()

找到数组元素中某符合项

const status = [
    { id: "3", name: "草稿" },
    { id: "0", name: "未发布" },
    { id: "1", name: "已发布" },
    { id: "2", name: "等待发布" },
    { id: "4", name: "已撤稿" },
]

const item_status = 1

status.find(option => option.id == item_status)
// (option) => { return option.id == item_status }

> Object { id: "1", name: "已发布" }

Array.reduce()

利用函数自带的累计器,统计出一些字段值出现的次数。第二参数作为累计器 acc 的初始值。

let channels = [
    { "id": 4, "title": "文化", "platform": "pc",  "type": "channel", "ordering": 4},
    { "id": 1, "title": "推荐", "platform": "app", "type": "channel", "ordering": 1},
    { "id": 7, "title": "人物", "platform": "app", "type": "channel", "ordering": 5}
]

const obj = channels.reduce((acc, item) => { 
    const platform = item.platform;
    const platformCount = acc[platform] ? acc[platform] + 1 : 1
    
    return {
        ...acc,
        [platform]: platformCount
    }
}, {})

console.log(obj)

> Object { pc: 1, app: 2 }
acc value records
> acc value
> Object {  }
> Object { pc: 1 }
> Object { pc: 1, app: 1 }

累计器寄存了上次函数返回的值,通过扩展运算符将累计器内可遍历属性复制到本次返回对象里。

链式操作

let channels = [
    { "id": 4, "title": "文化", "platform": "pc",  "type": "channel", "ordering": 4},
    { "id": 1, "title": "推荐", "platform": "app", "type": "channel", "ordering": 1},
    { "id": 7, "title": "人物", "platform": "app", "type": "channel", "ordering": 5},
    [{ "id": 8, "title": "绿色", "platform": "pc", "type": "channel", "ordering": 6}]
]

const chained = channels.reduce((acc, currValue) => {
        return acc.concat(currValue);
    }, [])
    .map(item => {
        return { ...item, disabled: item.id > 1 };
    })
    .filter(item => {
        return !item.disabled;
    })
    .map(item => item.title).join(", ")

console.log(chained); 

> "推荐"

配合箭头函数

const names = ['Will', 'Jack', 'Peter', 'Steve', 'John', 'Hugo', 'Mike']

const newSet = names
    .map((name, index) => ({
        id: index, 
        name //name: name
    }))
    .filter(({id} = man) => id % 2 === 0 ) //filter(man => man.id % 2 === 0 )
    .map(({name} = man) => [ name ])       //map(man => [ man.name ])
    .reduce((a, b) => a.concat(b))

console.log(newSet) //=>  ["Will", "Peter", "John", "Mike"]
    
> ["Will", "Peter", "John", "Mike"]

数组去重 Remove Array Duplicates (From Array Of Objects)

使用数组的各种内置方法都可以完成简单结构的数组去重,包括 map、foreach 、filter 、reduce

使用 Set 数据结构
[...new Set([1, 1, 2, 3, 4, 5, 5])]

Set 数据结构可实现纯数字数组去重

搭配 filter 和 IndexOf
// usage example:
var myArray = ['a', 1, 'a', 2, '1'];
var unique = myArray.filter((e, i, a) => a.indexOf(e) === i);

console.log(unique); // unique is ['a', 1, 2, '1']

不排除还有字符串等元素,使用 filter 筛选出所有第一次出现的元素。但现实未经过处理的数据结构长得更原始。

对象数组
const arr = [
    {place: "here",  name: "x", other: "other stuff1" },
    {place: "there", name: "x", other: "other stuff2" },
    {place: "here",  name: "y", other: "other stuff4" },
    {place: "here",  name: "z", other: "other stuff5" }
]

function getUniqueListBy(arr, key) {
    return [...new Map(arr.map(item => [item[key], item])).values()]
}

const arr1 = getUniqueListBy(arr, 'place')

对象数组中往往有多个键值,从中筛选出不重复的集合,最好是指定主键标识。另外还有使用 filter map 组合的版本:

function unique(array, fieldKey="id") {
    var res = array.filter(function(item, index, array){
        return array.map(item=>item[fieldKey]).lastIndexOf(item[fieldKey]) === index;
    })
    return res;
}

找出相同值 Find Duplicates

参考 unique 函数的变体,它过滤掉了相同的元素,很容易,修改 ===!== 就能实现过滤不同的元素。实现 find duplicates

let strArray = [ "q", "w", "w", "w", "e", "i", "u", "r"];
let findDuplicates = arr => arr.filter((item, index) => arr.indexOf(item) !== index)

console.log(findDuplicates(strArray)) // All duplicates
console.log([...new Set(findDuplicates(strArray))]) // Unique duplicates

对于对象数组,也有

const arr = [
    {place: "here",  name: "x", other: "other stuff1" },
    {place: "there", name: "x", other: "other stuff2" },
    {place: "here",  name: "y", other: "other stuff4" },
    {place: "here",  name: "z", other: "other stuff5" }
]

function duplicates(array, fieldKey="id") {
    var res = array.filter(function(item, index, array){
        return array.map(item=>item[fieldKey]).lastIndexOf(item[fieldKey]) !== index;
    })
    return res;
}

console.log(duplicates(arr, 'place'))

参考

JavaScript 作用域的延伸 — 闭包

发表评论
撰写评论