繁体   English   中英

如何根据数组字段中元素的出现次数对两个对象进行“排序”?

[英]How to 'sort' two objects based on number of occurrences of elements in an array field?

如果我有两个对象,并且它们内部都有两个数组字段,如下所示:

const list1 = {
  name: 'list-1',
  fruits: ['banana', 'strawberry', 'cherry'],
  vegs: ['lettuce', 'avocado', 'beans']
};

const list2 = {
  name: 'list-2',
  fruits: ['banana', 'apple', 'orange', 'watermelon'],
  vegs: ['potato', 'avocado', 'onion', 'cabbage']
};

然后,我传入两个数组,一个是水果,一个是蔬菜,例如:

const fruits = ['banana', 'strawberry'];
const vegetables = ['potato', 'lettuce', 'avocado'];

我如何订购这些对象,以便让水果和蔬菜数量最多的对象(基于传入的数组)位于顶部?

在这种情况下是list1 ,因为它在水果中既有“香蕉”和“草莓”,在蔬菜中也有“生菜”和“鳄梨”(即总共 4 个匹配项),而list2在全部的。

不确定这是否有意义,但是根据数组对两个对象进行排序的最有效方法是什么?

如果我正确理解您的问题,首先您需要将对象放入自己的数组中,然后您可以使用 Array.Prototype.sort: https ://developer.mozilla.org/en-US/docs/Web/JavaScript /参考/Global_Objects/数组/排序

例如。

const list1 = {
  name: 'list-1',
  fruits: ['banana', 'strawberry', 'cherry'],
  vegs: ['lettuce', 'avocado', 'beans']
};

const list2 = {
  name: 'list-2',
  fruits: ['banana', 'apple', 'orange', 'watermelon'],
  vegs: ['potato', 'avocado', 'onion', 'cabbage']
};

const arrayOfLists = [list1, list2]

arrayOfLists.sort((a, b) => (a.fruits.length + a.vegs.length) < (b.fruits.length + b.vegs.length) )

console.log(arrayOfLists) // Output = [list2, list1] because list 2 has more fruits and vegetables

首先,您需要定义一个intersection函数——一个给定两个列表的函数,它返回一个仅包含两个列表中的元素的新列表。 如果您想编写自己的版本,或者您可以使用大量库来完成此操作(例如RamdaLodash ), 这里有一个非常全面的答案。 您可以在排序函数中执行此操作,但不难想象在其他上下文中您会再次需要它,因此拥有可重用函数可能是有意义的。

假设您已经实现了此函数,您现在可以编写一个自定义比较函数,该函数可用于根据您提供的规则对形状为list1list2的对象进行排序,如下所示:

const compareByTotal = (a, b) => {
    const aTotal = intersection(a.fruits, fruits).length + intersection(a.vegs, vegetables).length;
    const bTotal = intersection(b.fruits, fruits).length + intersection(b.vegs, vegetables).length;
 
    return bTotal - aTotal;
}

最后,您可以在调用sort时将此函数用作参数以生成这些对象的排序列表:

[list1, list2].sort(compareByTotal);

我认为通过循环遍历它们并给每个分数打分然后选择一个获胜者是相当容易的

 const list1 = { name: 'list-1', fruits: ['banana', 'strawberry', 'cherry'], vegs: ['lettuce', 'avocado', 'beans'] }; const list2 = { name: 'list-2', fruits: ['banana', 'apple', 'orange', 'watermelon'], vegs: ['potato', 'avocado', 'onion', 'cabbage'] }; const fruits = ['banana', 'strawberry']; const vegetables = ['potato', 'lettuce', 'avocado']; const selectAWinner = (fruits,vegetables)=>{ let list1Score = 0; let list2Score = 0; fruits.forEach(fruit=>{ list1.fruits.forEach(fruitFromTheList=>{ if (fruitFromTheList === fruit) list1Score++ }) }) vegetables.forEach(vegetable=>{ list1.vegs.forEach(vegetableFromTheList=>{ if (vegetableFromTheList === vegetable) list1Score++ }) }) fruits.forEach(fruit=>{ list2.fruits.forEach(fruitFromTheList=>{ if (fruitFromTheList === fruit) list2Score++ }) }) vegetables.forEach(vegetable=>{ list2.vegs.forEach(vegetableFromTheList=>{ if (vegetableFromTheList === vegetable) list2Score++ }) }) if (list1Score > list2Score) document.write("list 1 wins with score " + list1Score) else if (list1Score < list2Score) document.write("list 2 wins with score " + list2Score) else document.write("it's a tie") // or do something else with the results } selectAWinner(fruits,vegetables)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM