是否有 javascript 或 coffeescript 功能(或者可能是下划线 groupBy 功能的扩展名)接收数组和等价比较器(具有两个参数的布尔函数,而不仅仅是一个参数)和基于的数组元素这个等价比较器?
作为我想要的一个例子:
areEquivalent = (p1, p2) ->
p1.birthYear == p2.birthYear and
p1.birthPlace == p2.birthPlace and
p1.gender == p2.gender
p1 = {name:'Anna', birthYear: 1990, birthPlace: 'Alaska', gender: 'female', hasCar: true, hasChildren: false}
p2 = {name:'John', birthYear: 1990, birthPlace: 'Alaska', gender: 'male', hasCar: true, hasChildren: false}
p3 = {name:'Dora', birthYear: 1980, birthPlace: 'Hawaii', gender: 'female', hasCar: true, hasChildren: true}
p4 = {name:'Lumi', birthYear: 1980, birthPlace: 'Hawaii', gender: 'female', hasCar: false, hasChildren: false}
p5 = {name:'Jack', birthYear: 1990, birthPlace: 'Alaska', gender: 'male', hasCar: false, hasChildren: false}
console.log areEquivalent p1, p2
# false
console.log areEquivalent p3, p4
# true
people = [p1, p2, p3, p4, p5]
console.log _.groupEquivalentObjects(people, areEquivalent)
# [ [p1], [p2,p5], [p3,p4] ]
答案 0 :(得分:4)
你能不能只传递_.groupBy()
和表达式来正确区分你的输入?
p1 = {name:'Anna', birthYear: 1990, birthPlace: 'Alaska', gender: 'female', hasCar: true, hasChildren: false}
p2 = {name:'John', birthYear: 1990, birthPlace: 'Alaska', gender: 'male', hasCar: true, hasChildren: false}
p3 = {name:'Dora', birthYear: 1980, birthPlace: 'Hawaii', gender: 'female', hasCar: true, hasChildren: true}
p4 = {name:'Lumi', birthYear: 1980, birthPlace: 'Hawaii', gender: 'female', hasCar: false, hasChildren: false}
p5 = {name:'Jack', birthYear: 1990, birthPlace: 'Alaska', gender: 'male', hasCar: false, hasChildren: false}
people = [p1, p2, p3, p4, p5]
groups = _.groupBy(people, (x) -> '' + x.birthYear + x.birthPlace + x.gender)
console.log groups
答案 1 :(得分:0)
谢谢大家的答案和建议。
目前我实施了这个不是非常理想的解决方案:
# Modifies the received array, by removing all the elements equivalent to the first one,
# and returning them in a separate array
extractAllObjectsEquivalentToFirst = (array, areEquivalent) ->
return [] if array.length == 0
first = array.shift()
equivalent = [first]
different = []
while array.length > 0
elem = array.shift()
if areEquivalent(elem,first)
equivalent.push elem
else
different.push elem
array[..] = different
return equivalent
groupEquivalentObjects = (array, areEquivalent) ->
arrayClone = array[..]
groups = []
previous = arrayClone.length
while arrayClone.length > 0
groups.push extractAllObjectsEquivalentToFirst(arrayClone, areEquivalent)
if arrayClone.length >= previous
console.warn "Array length did not decrease!"
arrayClone = []
previous = arrayClone.length
return groups
但确实更好的解决方案是为项目定义某种 hashCode()函数,并将该函数作为参数传递给 _。 GROUPBY()强>
在我目前的用例中,我需要比较的一些对象属性实际上是数组,我需要使用 _。isEqual( )等效比较器内的。
目前我懒得想办法定义一个“hashCode”函数,以确保我的用例值的明确等价。