我有一个像这样的对象数组:
[ { person: 'Fred', scoreTotal: 29 },
{ person: 'Alice', scoreTotal: 34 },
{ person: 'Alice', scoreTotal: 22 },
{ person: 'Mary', scoreTotal: 14 },
{ person: 'Bob', scoreTotal: 33 },
{ person: 'Bob', scoreTotal: 13 },
{ person: 'Bob', scoreTotal: 22 },
{ person: 'Joe', scoreTotal: 28 }]
Run Code Online (Sandbox Code Playgroud)
并且对于给定的人有多个对象 - >我想保持顶部的"X".例如:
一个.一个人的前1个结果结果如下所示:
[ { person: 'Fred', scoreTotal: 29 },
{ person: 'Alice', scoreTotal: 34 },
{ person: 'Mary', scoreTotal: 14 },
{ person: 'Bob', scoreTotal: 33 },
{ person: 'Joe', scoreTotal: 28 }]
Run Code Online (Sandbox Code Playgroud)
湾 一个人的前2个结果结果如下所示:
[ { person: 'Fred', scoreTotal: 29 },
{ person: 'Alice', scoreTotal: 34 },
{ person: 'Alice', scoreTotal: 22 },
{ person: 'Mary', scoreTotal: 14 },
{ person: 'Bob', scoreTotal: 33 },
{ person: 'Bob', scoreTotal: 22 },
{ person: 'Joe', scoreTotal: 28 }]
Run Code Online (Sandbox Code Playgroud)
有没有办法用Lodash这样的东西来实现这个目标?
我认为我正朝着正确的方向前进但尚未完全:
for (var i = 0; i < t.length - 1; i++) {
if (
t[i].golfer === t[i + 1].golfer &&
t[i].scoreTotal < t[i + 1].scoreTotal
) {
delete t[i];
}
Run Code Online (Sandbox Code Playgroud)
}
//删除"未定义的条目"
t = t.filter(function(el) {
return typeof el !== "undefined";
});
console.log(t);
Run Code Online (Sandbox Code Playgroud)
没有Underscore/Lodash,你可以很简单地做到这一点.按分数将数组从最高到最低排序.然后使用Array.filter.当过滤器通过阵列时,记录您看到每个人的次数,并在达到您想要的最高号码后开始返回false.
let arr = [ { person: 'Fred', scoreTotal: 29 },{ person: 'Alice', scoreTotal: 34 },{ person: 'Alice', scoreTotal: 22 },{ person: 'Mary', scoreTotal: 14 },{ person: 'Bob', scoreTotal: 33 },{ person: 'Bob', scoreTotal: 13 },{ person: 'Bob', scoreTotal: 22 },{ person: 'Joe', scoreTotal: 28 }]
function filterTop(arr, top) {
let counts = {}
return [...arr].sort((a, b) => b.scoreTotal - a.scoreTotal)
.filter(score => (counts[score.person] = (counts[score.person] || 0) +1 ) <= top)
}
console.log(filterTop(arr, 1))
console.log(filterTop(arr, 2))Run Code Online (Sandbox Code Playgroud)
这完全按照您想要的顺序使用您尝试使用的确切库(lodash)执行您想要的操作。我将这个过程分为以下步骤:
第一步:对数据进行分组。应该有一个包含所有“Bob”记录的数组,另一个包含所有“Joe”记录的数组,等等。我决定更进一步,只存储 ScoreTotal 而不是整个记录。
步骤 2:循环遍历每个数组,按降序对它们进行排序,然后切片到所需的“顶部”结果。
步骤 3:使用我们之前的发现来过滤原始数据,并且仅当我们对特定人员有精确的 ScoreTotal 匹配时才在结果中包含一条记录,并且每个此类分数仅包含一次,一路将其从我们的临时数组中删除,以便我们不要获取重复记录并返回比所需的“顶部”记录更多的记录。
// The magical function
function showTopResults(input, topResults)
{
// Step one: group like data together
var groupedData = _.reduce(input, function(result, value, key) {
if(typeof result[value.person] == 'undefined'){ result[value.person] = []; }
result[value.person].push(value.scoreTotal);
return result;
}, {});
// Step two: loop through person keys, sort it, then grab only the first "x" elements
_.forEach(groupedData, function(value, key) {
value = value.sort(function(a,b){ var n = b - a; return n ? n < 0 ? -1 : 1 : 0}); // first element is largest
groupedData[key] = value.slice(0, topResults); // we only want first x results, so we get largest only
});
// Step three: filter our elements only where we have a match
var filterResults = _.filter(input,function(o){
var idx = _.indexOf(groupedData[o.person],o.scoreTotal);
if( idx > -1)
{
groupedData[o.person].splice(idx, 1); // remove element so we don't get multiple elements of equal value
return true; // We have a match
} else {
return false; // not a match
}
});
return filterResults;
}
// Our input
var input = [
{ person: 'Fred', scoreTotal: 29 },
{ person: 'Alice', scoreTotal: 34 },
{ person: 'Alice', scoreTotal: 22 },
{ person: 'Mary', scoreTotal: 14 },
{ person: 'Bob', scoreTotal: 33 },
{ person: 'Bob', scoreTotal: 13 },
{ person: 'Bob', scoreTotal: 22 },
{ person: 'Joe', scoreTotal: 28 }
];
// Tests using our magical function
console.log(showTopResults(input, 1));
console.log(showTopResults(input, 2));Run Code Online (Sandbox Code Playgroud)
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
187 次 |
| 最近记录: |