js对象数组深度去重和深度排序

图片 1

collect.js 是 javascript的一个包装库,用于处理array和object,可以用它轻松得建立一个map或者修改现有的,可惜它的方法名实在有些难懂,特别是对我们这些英文不是母语的人来说,所以就想把它整理一下,以后也好查找。

 

collect.js 的 github: https://github.com/ecrmnn/collect.js

使用collect.js处理数组和对象

下面就按作用来分类:

https://github.com/ecrmnn/collect.js/#

  • 取出集合中的一部分
  • 分隔
  • 用于组合集合
  • 用于操作集合内的
  • 遍历
  • 判断集合的有效性
  • 过滤
  • 只操作对象和关联数组
  • 排序
  • 输出

 

用于取出集合中的一部分

  • all() 取出所有
collect([1, 2, 3]).all();

//=> [1, 2, 3]
  • forPage() 分页返回集合的一部分
const collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);

const forPage = collection.forPage(2, 3);

forPage.all();

//=> [4, 5, 6]
  • nth() 返回每个第x个元素,组成的集合
const collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);

const nth = collection.nth(4);

nth.all();

//=> ['a', 'e']

引入collect.js

用于计算出一个值的

  • avg() 算出平均值
collect([1, 3, 3, 7]).avg();

//=> 3.5

目标如果是对象或是一个多维数组,可以传入key值

const collection = collect([{
  name: 'JavaScript: The Good Parts', pages: 176
}, {
  name: 'JavaScript: The Definitive Guide', pages: 1096
}]);

collection.avg('pages');

//=> 636
  • sum([key|callback]) 合计

arg1 关联数组的key

collect([1, 2, 3]).sum();

//=> 6

传入第1个参数,可以只合计此列

const collection = collect([
  {name: 'JavaScript: The Good Parts', pages: 176},
  {name: 'JavaScript: The Definitive Guide', pages: 1096},
]);

也可以传入回调,决定哪些item应被合计

const collection = collect([
  {name: 'Desk', colors: ['Black', 'Mahogany']},
  {name: 'Chair', colors: ['Black']},
  {name: 'Bookcase', colors: ['Red', 'Beige', 'Brown']},
]);

const total = collection.sum(function (product) {
  return product.colors.length;
});

//=> 6

collection.sum('pages');

//=> 1272

* **count()** *计数*
```javascript
const collection = collect([1, 2, 3, 4]);

collection.count();

//=> 4```


* **max()** *最大值*
```javascript
const collection = collect([{
  value: 10
}, {
  value: -13
}, {
  value: 12
}, {
  unicorn: false
}]);

const max = collection.max('value');

//=> 12
  • min() 最小值
const collection = collect[{
  worth: 100
}, {
  worth: 900
}, {
  worth: 79
}]);

collection.min('worth');

//=> 79

collect([1, 2, 3, 4, 5]).min();

//=> 1
  • median() 中位数
collect([1, 3, 3, 6, 7, 8, 9]).median();

//=> 6

collect([{
  foo: 1
}, {
  foo: 1
}, {
  foo: 2
}, {
  foo: 4
}]).median('foo');

//=> 1.5
  • mode() 返回mode value,不好意思,这个实在没看懂,应该是一种数学计算
collect([{
  foo: 1
}, {
  foo: 1
}, {
  foo: 2
}, {
  foo: 4
}]).mode('foo');

//=> [1]

collect([1, 3, 3, 6, 7, 8, 9]).mode();

//=> [3]
  • pipe() 像管道一样,每次回调都可以对集合进行操作,下一次回调获得的集合是之前操作后的集合
const collection = collect([1, 2, 3]);

const piped = collection.pipe(function (collection) {
  return collection.sum();
});

//=> 6

https://github.com/ecrmnn/collect.js/#installation

分割

  • chunk() 分块取出
const collection = collect([1, 2, 3, 4, 5, 6, 7]);

const chunks = collection.chunk(4);

chunks.all();

//=> [[1, 2, 3, 4], [5, 6, 7]]
  • groupby() 按key来分组
const collection = collect([
  {
    product: 'Chair',
    manufacturer: 'IKEA'
  },
  {
    product: 'Desk',
    manufacturer: 'IKEA'
  },
  {
    product: 'Chair',
    manufacturer: 'Herman Miller'
  }
]);

const grouped = collection.groupBy('manufacturer');

grouped.all();

//=> {
//=>   IKEA: [
//=>     {
//=>       id: 100,
//=>       product: 'Chair',
//=>       manufacturer: 'IKEA',
//=>       price: '1490 NOK'
//=>     },
//=>     {
//=>       id: 150,
//=>       product: 'Desk',
//=>       manufacturer: 'IKEA',
//=>       price: '900 NOK'
//=>     }
//=>   ],
//=>   'Herman Miller': [
//=>     {
//=>       id: 200,
//=>       product: 'Chair',
//=>       manufacturer: 'Herman Miller',
//=>       price: '9990 NOK'
//=>     }
//=>   ]
//=> }

也可以传入回调函数,用于判断如何分组

const collection = collect([
  {
    product: 'Chair',
    manufacturer: 'IKEA'
  },
  {
    product: 'Desk',
    manufacturer: 'IKEA'
  },
  {
    product: 'Chair',
    manufacturer: 'Herman Miller'
  }
]);

const grouped = collection.groupBy(function (item, key) {
  return item.manufacturer.substring(0, 3);
});

grouped.all();

//=> {
//=>   IKE: [
//=>     {
//=>       id: 100,
//=>       product: 'Chair',
//=>       manufacturer: 'IKEA',
//=>       price: '1490 NOK'
//=>     },
//=>     {
//=>       id: 150,
//=>       product: 'Desk',
//=>       manufacturer: 'IKEA',
//=>       price: '900 NOK'
//=>     }
//=>   ],
//=>   Her: [
//=>     {
//=>       id: 200,
//=>       product: 'Chair',
//=>       manufacturer: 'Herman Miller',
//=>       price: '9990 NOK'
//=>     }
//=>   ]
//=> }
  • keyBy() 按key分组
const collection = collect([
  {
    product: 'Chair',
    manufacturer: 'IKEA'
  }, {
    product: 'Desk',
    manufacturer: 'IKEA'
  }, {
    product: 'Chair',
    manufacturer: 'Herman Miller'
  }
]);

const keyed = collection.keyBy('manufacturer');

keyed.all();

//=> {
//=>   IKEA: {
//=>     product: 'Desk',
//=>     manufacturer: 'IKEA'
//=>   },
//=>   'Herman Miller': {
//=>     product: 'Chair',
//=>     manufacturer: 'Herman Miller'
//=>   }
//=> }

也可以传入一个回调来处理key,然后用处理过的key来分组

const keyedUpperCase = collection.keyBy(function (item) {
  return item['manufacturer'].toUpperCase();
});

keyedUpperCase.all();

//=> {
//=>   IKEA: {
//=>     product: 'Desk',
//=>     manufacturer: 'IKEA'
//=>   },
//=>   'HERMAN MILLER': {
//=>     product: 'Chair',
//=>     manufacturer: 'Herman Miller'
//=>   }
//=> }
  • partition() 按回调的返回值分区
const collection = collect([1, 2, 3, 4, 5, 6]);

const [underThree, overThree] = collection.partition(function (i) {
  return i < 3;
});
  • split(count,[index,[replaces]]) 将集合分割成n份
const collection = collect([1, 2, 3, 4, 5]);

const groups = collection.split(3);

//=> [[1, 2], [3, 4], [5]]

第三个参数可以顺便替换原有集合的items

const collection = collect([1, 2, 3, 4, 5]);

const chunk = collection.splice(2, 1, [10, 11]);

chunk.all()

//=> [3]

collection.all();

//=> [1, 2, 10, 11, 4, 5]
npm install collect.js --save

用于处理多维对象或数组

  • collapse() 折叠,就是将集合中所有嵌套的集合,都平铺开来,输出成一个集合
const collection = collect([[1], [{}, 5, {}], ['xoxo']]);

const collapsed = collection.collapse();

collapsed.all();

//=> [1, {}, 5, {}, 'xoxo']

const collection = collect([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);

const collapsed = collection.collapse();

collapsed.all();

//=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
  • flatten() 和collapse类似,暂时没发现有什么区别
const collection = collect({
  club: 'Liverpool',
  players: ['Sturridge', 'Firmino', 'Coutinho']
});

const flattened = collection.flatten();

flattened.all();

//=> ['Liverpool', 'Sturridge', 'Firmino', 'Coutinho'];

也可以传入深度

const collection = collect({
  Apple: [{
    name: 'iPhone 6S',
    brand: 'Apple'
  }],
  Samsung: [{
    name: 'Galaxy S7',
    brand: 'Samsung'
  }]
});

const flattened = collection.flatten(1);

flattened.all();

//=> [
//=>   {name: 'iPhone 6S', brand: 'Apple'},
//=>   {name: 'Galaxy S7', brand: 'Samsung'}
//=> ]
  • combine() 组合,将原集合作为key,参数集合作为value,组合成一个对象
const collection = collect(['name', 'number']);

const combine = collection.combine(['Steven Gerrard', 8]);

combine.all();

//=> {
//=>   name: 'Steven Gerrard',
//=>   number: 8
//=> }
  • zip() 将原集合当作key,参数集合当成value,组成关联数组
const collection = collect(['Chair', 'Desk']);

const zipped = collection.zip([100, 200]);

zipped.all();

//=> [['Chair', 100], ['Desk', 200]]

用于组合集合

  • concat() 合并,其实和merge有点像,将一个或多个item加入到集合中
const collection = collect([1, 2, 3]);

collection
  .concat(['a', 'b', 'c'])
  .concat({
    name: 'Steven Gerrard',
    number: 8
  });

collection.all();

//=> [1, 2, 3, 'a', 'b', 'c', 'Steven Gerrard', 8]
  • crossJoin() 排列组合
const collection = collect([1, 2]);

collection.crossJoin(['a', 'b']);

collection.all();

//=> [
//=>   [1, 'a'],
//=>   [1, 'b'],
//=>   [2, 'a'],
//=>   [2, 'b'],
//=> ]
  • union(collection) 组合集合,按key来判断,如果有重复的key,就用原集合的item
const collection = collect({
  a: 'A',
  b: 'B'
});

const union = collection.union({
  a: 'AAA',
  c: 'CCC',
  b: 'BBB'
});

union.all();

//=> {
//=>   a: 'A',
//=>   b: 'B',
//=>   c: 'CCC'
//=> }
  • diff() 取第一个集合中有的,但第二个集合中没有的item,组成集合
const collection = collect([1, 2, 3, 4, 5]);

const diff = collection.diff([1, 2, 3, 9]);

diff.all();

//=> [4, 5]
  • diffAssoc() 和diff()类似,但针对对象或关联数组比较,会同时比较key和value
const collection = collect({
  color: 'orange',
  type: 'fruit',
  remain: 6,
});

const diff = collection.diffAssoc({
  color: 'yellow',
  type: 'fruit',
  remain: 3,
  used: 6,
});

diff.all();

//=> { color: 'orange', remain: 6 };
  • diffKeys() 和diff()一样,但只比较key
const collection = collect({
  a: 'a',
  b: 'b',
  c: 'c',
  d: 'd'
});

const diff = collection.diffKeys({
  b: 'b',
  d: 'd'
});

diff.all();

//=> {a: 'a', c: 'c'}
  • intersect() 取交集
const collection = collect([1, 2, 3, 4, 5]);

intersect = collection.intersect([1, 2, 3, 9]);

intersect.all();

//=> [1, 2, 3]
  • intersectByKeys() 按key取交集
const collection = collect({
    serial: 'UX301',
    type: 'screen',
    year: 2009,
});

const intersect = collection.intersectByKeys({
  reference: 'UX404',
  type: 'tab',
  year: 2011,
});

intersect.all();

// ['type' => 'screen', 'year' => 2009]

const firstCollection = collect([1, 2, 3, 4, 5]);
const secondCollection = collect([1, 2, 3, 9]);

intersect = firstCollection.intersect(secondCollection);

intersect.all();

//=> [1, 2, 3]
  • merge() 组合两个相同结构的集合
const collection = collect({
  id: 1,
  price: 29
});

const merged = collection.merge({
  price: 400,
  discount: false
});

merged.all();

//=> {id: 1, price: 400, discount: false}

const collection = collect(['Unicorn', 'Rainbow']);

const merged = collection.merge(['Sunshine', 'Rainbow']);

merged.all();

//=> ['Unicorn', 'Rainbow', 'Sunshine', 'Rainbow']
<script src="https://cdn.jsdelivr.net/npm/collect.js@4.0.25/build/collect.min.js"></script>

用于操作集合内的

  • contains() * 判断集合内是否指定的key*

操作对象时,类似于hasOwnProperty
操作数组时,类似于indexOf(value) === -1

操作对象

const collection = collect({
  name: 'Steven Gerrard',
  number: 8
});

collection.contains('name');
//=> true

collection.contains('age');
//=> false

对数组操作

const collection = collect([1, 2, 3]);

collection.contains(3);
//=> true

对key和value一起判断

const collection = collect({
  name: 'Steven Gerrard',
  number: 8
});

collection.contains('name', 'Steve Jobs');
//=> false
  • has() 判断是否存在相应的key

操作对象时,效果应该与 contains() 相同

const collection = collect({
  animal: 'unicorn',
  ability: 'magical'
});

collection.has('ability');

//=> true
  • get() 按key取出value,如果找不取,就返回第二个参数(即默认值)
const collection = collect({
  firstname: 'Chuck',
  lastname: 'Norris'
});

collection.get('lastname');

//=> Norris

collection.get('middlename');
//=> null

第二个参数作为找到不时,返回的默认值

const collection = collect({
  firstname: 'Chuck',
  lastname: 'Norris'
});

collection.get('middlename', 'default-value');
//=> default-value

默认值也可以是回调

const collection = collect({
  firstname: 'Chuck',
  lastname: 'Norris'
});

collection.get('middlename', function () {
  return 'default-value';
});

//=> default-value
  • search() 按value获取key
const collection = collect([2, 4, 6, 8]);

collection.search(4);

//=> 1

第二个参数传入true时,所有value比较时,整数字符串会被当时等级的整数比较

collection.search('4', true);

//=> false

也可以用回调查找

collection.search(function (item, key) {
  return item > 5;
});

//=> 2
  • first() 取出第一个item,也可以传入一个回调函数
collect([1, 2, 3, 4]).first();

//=> 1

collect([1, 2, 3, 4]).first(function (item) {
  return item > 1;
});

//=> 2
  • firstWhere() 按key-value来判断,找出第一个item
const collection = collect([
    {name: 'Regena', age: 12},
    {name: 'Linda', age: 14},
    {name: 'Diego', age: 23},
    {name: 'Linda', age: 84},
]);

collection.firstWhere('name', 'Linda');

//=> { name: 'Linda', age: 14 }
  • last() 返回最后一个item
const collection = collect([1, 2, 3]);

const last = collection.last(function (item) {
  return item > 1;
});

//=> 3

collect([1, 2, 3, 4]).last();

//=> 4
  • forget() 用key删除一个item
const collection = collect({
  name: 'Steven Gerrard',
  number: 8
});

collection.forget('number');

collection.all();

//=> {
//=>   name: 'Steven Gerrard'
//=> }
  • pad() *用固定的值填充集合,第一个参数是填充后的集合长度,第二个参数是填充的值
const collection = collect(['A', 'B', 'C']);

let filtered = collection.pad(5, 0);

filtered.all();

//=> ['A', 'B', 'C', 0, 0]

filtered = collection.pad(-5, 0);

filtered.all();

//=> [0, 0, 'A', 'B', 'C']
  • pop() 压出最后一个item
const collection = collect([1, 2, 3, 4, 5]);

collection.pop();

//=> 5

collection.all();

// => [1, 2, 3, 4]
  • prepend() 压入一个item,并将它放在集合的第一个
const collection = collect([1, 2, 3, 4, 5]);

collection.prepend(0);

collection.all();

//=> [0, 1, 2, 3, 4, 5]

也可以传入第二个参数,作为压入item的key

const collection = collect({
  product: 'iPhone 6s'
});

collection.prepend('Apple', 'brand');

collection.all():

//=> {
//=>   brand: 'Apple',
//=>   product: 'iPhone 6s'
//=> }
  • pull() 删除指定key的item,(我觉得叫delete更合适)
const collection = collect({
  firstname: 'Michael',
  lastname: 'Cera'
});

collection.pull('lastname');

//=> Cera

collection.all();

//=> {firstname: 'Michael'}
  • push() 压入一个item,放在集合最后
const collection = collect([1, 2, 3, 4]);

collection.push(5);

collection.all();

//=> [1, 2, 3, 4, 5]
  • put() 像是加入一个item到集合中,但没看懂示例
const collection = collect(['JavaScript', 'Python']);

collection.put('Ruby');

collection.all();

//=> ['JavaScript', 'Python', 'Ruby']
  • shift() 从头部压出item
const collection = collect([1, 2, 3, 4, 5]);

collection.shift();

//=> 1

collection.all();

//=> [2, 3, 4, 5]
  • random() 随机取出item
const collection = collect([1, 2, 3, 4, 5]);

collection.random();

//=> 4 (retrieved randomly)

可以指定取出几个

const random = collection.random(3);

//=> [5, 3, 4] (retrieved randomly)
  • reduce() 和pipe()类似,只是每次回调传入[上一个item,当前item]两个参数
const collection = collect([1, 2, 3]);

const total = collection.reduce(function (carry, item) {
  return carry + item;
});

//=> 6
  • splice() 删除多个item,第二个参数是开始的index
const collection = collect([1, 2, 3, 4, 5]);

const chunk = collection.splice(2);

chunk.all();

//=> [3, 4, 5]

collection.all();

//=> [1, 2]

const collection = collect([1, 2, 3, 4, 5]);

const chunk = collection.splice(2, 1);

chunk.all();

//=> [3]

collection.all();

//=> [1, 2, 4, 5]
  • take(n) 取出n个item

arg1 指取出几个item

const collection = collect([0, 1, 2, 3, 4, 5]);

const chunk = collection.take(3);

chunk.all();

//=> [0, 1, 2]

 

遍历

  • each() 遍历每一个item,但不修改集合
let sum = 0;

const collection = collect([1, 3, 3, 7]);

collection.each(function (item) {
  sum += item;
});

//=> console.log(sum);
//=> 14

如果你在回调中返回false,则会立刻停止遍历

let sum = 0;

const collection = collect([1, 3, 3, 7]);

collection.each(function (item) {
  if (item > 3) {
    return false;
  }

  sum += item;
});

//=> console.log(sum);
//=> 7
  • eachSpread() each()的递归版本,它会递归调用each()
const collection = collect([['John Doe', 35], ['Jane Doe', 33]]);

collection.eachSpread((name, age) => {
    //
});

同样的,你也可以在回调中返回false,就能立刻停止遍历

collection.eachSpread((name, age) => {
    return false;
});
  • transform() 遍历集合,每个回调的返回值会替换当成item
const collection = collect([1, 2, 3, 4, 5]);

collection.transform(function (item, key) {
  return item * 2;
});

collection.all();

//=> [2, 4, 6, 8, 10]
  • flatMap() 用回调遍历集合,在回调中可以获取value,利用回调中的返回值,按原集合格式,组成新的集合,并返回
const collection = collect([
 { name: 'Robbie Fowler' },
 { nickname: 'The God' },
 { position: 'Striker' },
]);

const flatMapped = collection.flatMap(values => values.map(value => value.toUpperCase()));

flatMapped.all();

//=> {
//=>   name: 'ROBBIE FOWLER',
//=>   nickname: 'THE GOD',
//=>   position: 'STRIKER'
//=> }
  • map() 遍历每个value,用回调进行修改后,返回新集合
const collection = collect([1, 2, 3, 4, 5]);

const multiplied = collection.map(function (item) {
  return item * 2;
});

multiplied.all();

//=> [2, 4, 6, 8, 10]
  • mapSpread() map()的递归版本
const collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

const chunks = collection.chunk(2);

const sequence = chunks.mapSpread((odd, even) => {
    return odd + even;
});

sequence.all();

//=> [1, 5, 9, 13, 17]
  • slice() 从某一个index开始分片
const collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

const slice = collection.slice(4);

slice.all();

//=> [5, 6, 7, 8, 9, 10]

第二个参数是返回的item长度

const slice = collection.slice(4, 2);

slice.all();

//=> [5, 6]
  • mapInto() 传入的回调是一个类的构造器,此方法将每个item传入回调,作为构造器的参数,回调器的返回即是一个对象,最终返回一组对象
const Player = function (name) {
  this.name = name;
};

const collection = collect([
  'Roberto Firmino',
  'Sadio Mané',
]);

const players = collection.mapInto(Player);

players.all();

//=> [
//=>   Player { name: 'Roberto Firmino' },
//=>   Player { name: 'Sadio Mané' },
//=> ]
  • mapToDirctionary() 遍历后,返回一组关联数组
const collection = collect([
  { id: 1, name: 'a' },
  { id: 2, name: 'b' },
  { id: 3, name: 'c' },
  { id: 4, name: 'b' },
]);

const groups = collection.mapToDictionary(item => [item.name, item.id]);

groups.all();

//=> {
//=>   a: [1],
//=>   b: [2, 4],
//=>   c: [3],
//=> }
  • mapToGroups 和mapToDirctionary()一样,只是这次回调的第二个参数可以接受key
const collection = collect([
  { id: 1, name: 'A' },
  { id: 2, name: 'B' },
  { id: 3, name: 'C' },
  { id: 4, name: 'B' },
]);

const groups = collection.mapToGroups(function (item, key) {
  return [item.name, item.id];
});

//=> {
//=>   A: [1],
//=>   B: [2, 4],
//=>   C: [3],
//=> }
  • mapWithKeys() 和map一样,只是回调应该返回一个[key,value]的数组,最终方法返回一组关联数组
const collection = collect([{
    'name': 'John',
    'department': 'Sales',
    'email': 'john@example.com'
  }, {
    'name': 'Jane',
    'department': 'Marketing',
    'email': 'jane@example.com'
  }]);

const keyed = collection.mapWithKeys(function (item) {
  return [item.email, item.name];
});

keyed.all();

//=> {
//=>   'john@example.com': 'John',
//=>   'jane@example.com': 'Jane',
//=> }

深度去重

判断集合的有效性

  • every() 判断集合中的item是不是每一个都有效,如何才算有效,就由回调函数来判断
collect([1, 2, 3, 4]).every(function (value, key) {
  return value > 2;
});

//=> false
  • isEmpty() 是否为空集合
collect([]).isEmpty();

//=>  true
  • isNotEmpty 是否为非空集合
collect([1, 2, 3]).isNotEmpty();

//=>  true

https://github.com/ecrmnn/collect.js/#unique

过滤

  • except() 去除传入的item,并返回新集合

操作对象时,按key判断
操作数组时,按value判断
和diff()相比,好像只是把原集合和传入集合对调了一下

const collection = collect({
  product_id: 1,
  price: 100,
  discount: false,
});

const filtered = collection.except(['price', 'discount']);

filtered.all();

//=> {product_id: 1}

collect([1, 2, 3, 4]).except([2, 12]).all();

//=> [1, 3, 4]
  • only() 和except是相反的操作
const collection = collect({
  id: 12,
  name: 'John Doe',
  email: 'john@doe.com',
  active: true,
});

const filtered = collection.only(['name', 'email']);

filtered.all();

//=> {name: 'John Doe', email: 'john@doe.com'}
  • filter() 按回调的返回值过滤集合,并返回过滤后的集合
const collection = collect([1, 2, 3, 4]);

const filtered = collection.filter(function (value, key) {
    return value > 2;
});

filtered.all();

//=> [3, 4]

也可以传入空回调,这样等于false的值,都会被过滤掉

const collection = collect([0, 1, 2, null, 3, 4, undefined, 5, 6, 7, [], 8, 9, {}, 10]);

const filtered = collection.filter();

filtered.all();

//=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  • reject() filter()的反操作,回调中返回true的item,都将被去除后返回
const collection = collect([1, 2, 3, 4]);

const filtered = collection.reject(function (value) {
  return value > 2;
});

//=> [1, 2]
  • where(key,[op],value) 查找key-value对,并将其全部返回

key 二维表的key
op 此参数可以是一个操作符,包括<,<=,>,>=
value 二维表的值

const collection = collect([
  {product: 'Desk', price: 200},
  {product: 'Chair', price: 100},
  {product: 'Bookcase', price: 150},
  {product: 'Door', price: 100},
]);

* **whereIn(key,collection)** *where的in-array操作*
```javascript
const collection = collect([
  {product: 'Desk', price: 200},
  {product: 'Chair', price: 100},
  {product: 'Bookcase', price: 150},
  {product: 'Door', price: 100},
]);

const filtered = collection.whereIn('price', [100, 150]);

filtered.all();

//=> [
//=>   {product: 'Chair', price: 100},
//=>   {product: 'Bookcase', price: 150},
//=>   {product: 'Door', price: 100},
//=> ]
  • whereNotIn(key,collection) where的not in-array操作
const collection = collect([
  { product: 'Desk', price: 200 },
  { product: 'Chair', price: 100 },
  { product: 'Bookcase', price: 150 },
  { product: 'Door', price: 100 }
]);

const filtered = collection.whereNotIn('price', [150, 200]);

filtered.all();

//=> [
//=>   { product: 'Chair', price: 100 },
//=>   { product: 'Door', price: 100 }
//=> ]

const filtered = collection.where('price', 100);

filtered.all();

//=> [
//=> {product: 'Chair', price: 100},
//=> {product: 'Door', price: 100}
//=> ]

第2个参数还可以是一个操作符
```javascript
const filtered = collection.where('price', '!==', 100);

filtered.all();

//=> [
//=>   {product: 'Desk', price: 200},
//=>   {product: 'Bookcase', price: 150}
//=> ]
  • unique(key|callback) 取重
const collection = collect([1, 1, 1, 2, 3, 3]);

const unique = collection.unique();

unique.all();

//=> [1, 2, 3]

在关联数组时,可以只去重某一列

const collection = collect([
  {name: 'iPhone 6', brand: 'Apple', type: 'phone'},
  {name: 'iPhone 5', brand: 'Apple', type: 'phone'},
  {name: 'Apple Watch', brand: 'Apple', type: 'watch'},
  {name: 'Galaxy S6', brand: 'Samsung', type: 'phone'},
  {name: 'Galaxy Gear', brand: 'Samsung', type: 'watch'}
]);

const unique = collection.unique('brand');

unique.all();

//=> [
//=>   {name: 'iPhone 6', brand: 'Apple', type: 'phone'},
//=>   {name: 'Galaxy S6', brand: 'Samsung', type: 'phone'},
//=> ]

也可以用callback来决定,哪些item要去重

const collection = collect([
  {name: 'iPhone 6', brand: 'Apple', type: 'phone'},
  {name: 'iPhone 5', brand: 'Apple', type: 'phone'},
  {name: 'Apple Watch', brand: 'Apple', type: 'watch'},
  {name: 'Galaxy S6', brand: 'Samsung', type: 'phone'},
  {name: 'Galaxy Gear', brand: 'Samsung', type: 'watch'}
]);

const unique = collection.unique(function (item) {
  return item.brand + item.type;
});

unique.all();

//=> [
//=>   {name: 'iPhone 6', brand: 'Apple', type: 'phone'},
//=>   {name: 'Apple Watch', brand: 'Apple', type: 'watch'},
//=>   {name: 'Galaxy S6', brand: 'Samsung', type: 'phone'},
//=>   {name: 'Galaxy Gear', brand: 'Samsung', type: 'watch'},
//=> ]

简单数组去重

只操作对象和关联数组

  • flip() 反转key和value
const collection = collect({
  name: 'Steven Gerrard',
  number: 8
});

const flipped = collection.flip();

flipped.all();

//=> {
//=>   'Steven Gerrard': 'name',
//=>   '8': 'number'
//=> }
  • implode() 把item展开

操作对象(关联数组)时,可以指定一个key,将此key对应的value展开

const collection = collect([{
    product: 'Chair',
    manufacturer: 'IKEA',
  }, {
    product: 'Desk',
    manufacturer: 'IKEA',
  }, {
    product: 'Chair',
    manufacturer: 'Herman Miller',
  }]);

collection.implode('product', ',');

//=> Chair, Desk, Chair

操作一维数组时,可以传入第二个参数当成连接符使用

collect([1, 2, 3, 4, 5]).implode('-');

//=> 1-2-3-4-5
  • keys() 只返回key列表
const collection = collect([{
  name: 'Steven Gerrard',
  number: 8
}, {
  club: 'Liverpool',
  nickname: 'The Reds'
}]);

keys = collection.keys();

//=> ['name', 'number', 'club', 'nickname']
  • values() 只返回value的列表
const collection = collect({a: 'xoxo', b: 'abab', 'c': '1337', 1337: 12});

const values = collection.values();

values.all();

//=> [12, 'xoxo', 'abab', '1337']
  • pluck() 将集合看成一个二维表格,返回某一列的value组成的集合
const collection = collect([{
  id: 78,
  name: 'Aeron'
}, {
  id: 79,
  name: 'Embody'
}]);

const plucked = collection.pluck('name');

plucked.all();

//=> ['Aeron', 'Embody']

返回的集合的key,可以用表格中的另一列的value

const collection = collect([{
  id: 78,
  name: 'Aeron'
}, {
  id: 79,
  name: 'Embody'
}]);

const plucked = collection.pluck('name', 'id');

plucked.all();

//=> {
//=>   78: 'Aeron',
//=>   79: 'Embody'
//=> }
const collection = collect([1, 1, 1, 2, 3, 3]);

const unique = collection.unique();

unique.all();

//=> [1, 2, 3]

输出

  • dd() 输出到console.log,并结束程序
const collection = collect([1, 2, 3]).dd();

//=> [1, 2, 3]
//=> (Exits node.js process)
  • dump() 和dd()一样,只是不中断输出
collect([1, 2, 3, 4])
  .dump()
  .map(item => item * 2)
  .dump();

//=> [1, 2, 3, 4]
//=> [2, 4, 6, 8]
  • toArray() 转成array
const collection = collect([1, 2, 3, 'b', 'c']);

collection.toArray();

//=> [1, 2, 3, 'b', 'c']

const collection = collect({
  name: 'Elon Musk',
  companies: [
    'Tesla',
    'Space X',
    'SolarCity'
  ]
});

collection.toArray();

//=> ['Elon Musk', ['Tesla', 'Space X', 'SolarCity']]
  • toJson() 转成json
const collection = collect({
  id: 384,
  name: 'Rayquaza',
  gender: 'NA'
});

const json = collection.toJson();

//=> {"id": 384, "name": "Rayquaza", "gender": "NA"}
  • unwrap() 转回原有的对象
const collection = collect([1, 2, 3]);

collect().unwrap(collection);

//=> [1, 2, 3]

对象数组去重

排序

  • soft() 排序
const collection = collect([5, 3, 1, 2, 4]);

const sorted = collection.sort();

sorted.all();

//=> [1, 2, 3, 4, 5]

可以用回调排序

const collection = collect([5, 3, 1, 2, 4]);

const sorted = collection.sort(function (a, b) {
  return b - a;
});

sorted.all();

//=> [5, 4, 3, 2, 1]
  • shuffle() 乱序排列
const collection = collect([1, 2, 3, 4, 5]);

const shuffled = collection.shuffle();

shuffled.all();

//=> [3, 5, 1, 2, 4] (generated randomly)
  • reverse() 反转集合,即倒序排列
const collection = collect([1, 2, 3, 4, 5]);

const reversed = collection.reverse();

reversed.all();

//=> [5, 4, 3, 2, 1]
  • softBy 按key来排序
const collection = collect([
  {name: 'Desk', price: 200},
  {name: 'Chair', price: 100},
  {name: 'Bookcase', price: 150},
]);

const sorted = collection.sortBy('price');

sorted.all();

//=> [
//=>   {name: 'Chair', price: 100},
//=>   {name: 'Bookcase', price: 150},
//=>   {name: 'Desk', price: 200},
//=> ]

const collection = collect([
  {name: 'Desk', colors: ['Black', 'Mahogany']},
  {name: 'Chair', colors: ['Black']},
  {name: 'Bookcase', colors: ['Red', 'Beige', 'Brown']},
]);

const sorted = collection.sortBy(function (product, key) {
  return product['colors'].length;
});

sorted.all();

//=> [
//=>   {name: 'Chair', colors: ['Black']},
//=>   {name: 'Desk', colors: ['Black', 'Mahogany']},
//=>   {name: 'Bookcase', colors: ['Red', 'Beige', 'Brown']},
//=> ]
  • sortByDesc() 和sortBy(),只是排序方向来降序
const collection = collect([
  { name: 'iPhone 6', brand: 'Apple', type: 'phone' },
  { name: 'iPhone 5', brand: 'Apple', type: 'phone' },
  { name: 'Apple Watch', brand: 'Apple', type: 'watch' },
  { name: 'Galaxy S6', brand: 'Samsung', type: 'phone' },
  { name: 'Galaxy Gear', brand: 'Samsung', type: 'watch' },
]);

const unique = collection.unique('brand');

unique.all();

//=> [
//=>   { name: 'iPhone 6', brand: 'Apple', type: 'phone' },
//=>   { name: 'Galaxy S6', brand: 'Samsung', type: 'phone' },
//=> ]

扩展

  • macro() 可以为collection类定义一个自定义方法

但不能用于链式调用

collect().macro('uppercase', function () {
  return this.map(function (item) {
    return item.toUpperCase();
  });
});

const collection = collect(['a', 'b', 'c']);

collection.uppercase();

collection.all();

//=> ['A', 'B', 'C']
  • tap(callback(collection)) 给回调函数传入合集,但不允许修改集合

此方法常用于链式调用

const collect([2, 4, 3, 1, 5])
  .sort()
  .tap(function (collection) {
    console.log(collection.all());

    //=> [1, 2, 3, 4, 5]
  })
  .shift();

//=> 1
  • unless(bool,callback) 持续用回调循环,除非第一个参数的值为假

bool 当为假时,循环结束
callback = function(collection),即callback的第1个参数是集合本身

const collection = collect([1, 2, 3]);

collection.unless(false, function (collection) {
  return collection.push(4);
});

collection.all();

//=> [1, 2, 3, 4]
  • when(bool,callback) 持续用回调循环,除非第一个参数的值为假

bool 当为真时,循环结束
callback = function(collection),即callback的第1个参数是集合本身

const collection = collect([1, 2, 3]);

collection.when(true, function (collection) {
  return collection.push(4);
});

collection.all();

//=> [1, 2, 3, 4]
  • wrap() 包装
const collection = collect().wrap([1, 2, 3]);

collection.all();

//=> [1, 2, 3]

对象数组回调函数处理去重

const collection = collect([
  { name: 'iPhone 6', brand: 'Apple', type: 'phone' },
  { name: 'iPhone 5', brand: 'Apple', type: 'phone' },
  { name: 'Apple Watch', brand: 'Apple', type: 'watch' },
  { name: 'Galaxy S6', brand: 'Samsung', type: 'phone' },
  { name: 'Galaxy Gear', brand: 'Samsung', type: 'watch' },
]);

const unique = collection.unique(function (item) {
  return item.brand + item.type;
});

unique.all();

//=> [
//=>   { name: 'iPhone 6', brand: 'Apple', type: 'phone' },
//=>   { name: 'Apple Watch', brand: 'Apple', type: 'watch' },
//=>   { name: 'Galaxy S6', brand: 'Samsung', type: 'phone' },
//=>   { name: 'Galaxy Gear', brand: 'Samsung', type: 'watch' },
//=> ]

本文由金沙官网线上发布于Web前端,转载请注明出处:js对象数组深度去重和深度排序

您可能还会对下面的文章感兴趣: