如何使用Underscore来select最大的数组元素
How to use Underscore to select the largest array element
我有以下数组:
var array = [[{key1: 1, key2: thing}, {key1: 3, key2: thing}],
[{key1: 4, key2: stuff}, {key1: 2, key2: stuff}],
[{key1: 3, key2: onlyOne}]]
我需要取出所有少于两个对象的数组,每个剩余的数组可能有 'n' 个对象应该只包含具有最小 key1 的对象。最后我会:
var updatedArray = [[{key1: 1, key2: thing}],[{key1: 2, key2: stuff}]]
我怎样才能使用 Underscore 得到这个?
现在我已经完成了:
var soFar = _.filter(_.groupBy(_.map(array, function(n){return _.find(n)}),
"key2"), function(n){return n.length > 1});
//soFar = [[{key1: 1, key2: thing}, {key1: 3, key2: thing}],
//[{key1: 4, key2: stuff}, {key1: 2, key2: stuff}]]`
这让我摆脱了只有一个对象的数组,但我无法根据对象的比较找出下一部分来修改每个数组。
看来你把事情复杂化了。这是一个纯 ES5 示例,但很容易转换为 underscore
' 语法。
var thing = 'thing';
var stuff = 'stuff';
var onlyOne = 'onlyOne';
var array = [
[{
key1: 1,
key2: thing
}, {
key1: 3,
key2: thing
}],
[{
key1: 4,
key2: stuff
}, {
key1: 2,
key2: stuff
}],
[{
key1: 3,
key2: onlyOne
}]
];
var b = array.filter(function(item) {
return item.length > 1;
}).map(function(item) {
return [item.slice().sort(function(x, y) {
return x.key1 - y.key1;
}).shift()];
});
document.getElementById('out').textContent = JSON.stringify(b, null, 2);
console.log(b);
<pre id="out"></pre>
下划线
var thing = 'thing';
var stuff = 'stuff';
var onlyOne = 'onlyOne';
var array = [
[{
key1: 1,
key2: thing
}, {
key1: 3,
key2: thing
}],
[{
key1: 4,
key2: stuff
}, {
key1: 2,
key2: stuff
}],
[{
key1: 3,
key2: onlyOne
}]
];
var b = _.chain(array).filter(function(item) {
return item.length > 1;
}).map(function(item) {
return [_.chain(item).map(_.identity).sortBy('key1').first()];
});
document.getElementById('out').textContent = JSON.stringify(b, null, 2);
console.log(b);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<pre id="out"></pre>
或者您可以使用 reduce
而不是 filter
和 map
并为自己保存一个循环以及 chain
包装器。
var thing = 'thing';
var stuff = 'stuff';
var onlyOne = 'onlyOne';
var array = [
[{
key1: 1,
key2: thing
}, {
key1: 3,
key2: thing
}],
[{
key1: 4,
key2: stuff
}, {
key1: 2,
key2: stuff
}],
[{
key1: 3,
key2: onlyOne
}]
];
var b = _.reduce(array, function(acc, item) {
if (item.length > 1) {
acc.push([_.chain(item).map(_.identity).sortBy('key1').first()]);
}
return acc;
}, []);
document.getElementById('out').textContent = JSON.stringify(b, null, 2);
console.log(b);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<pre id="out"></pre>
而不是 slice
(或 map
)和 sort
(或 sortBy
),您可以使用 min
并进一步减少 chain
var thing = 'thing';
var stuff = 'stuff';
var onlyOne = 'onlyOne';
var array = [
[{
key1: 1,
key2: thing
}, {
key1: 3,
key2: thing
}],
[{
key1: 4,
key2: stuff
}, {
key1: 2,
key2: stuff
}],
[{
key1: 3,
key2: onlyOne
}]
];
var b = _.reduce(array, function(acc, item) {
if (item.length > 1) {
acc.push([_.min(item, 'key1')]);
}
return acc;
}, []);
document.getElementById('out').textContent = JSON.stringify(b, null, 2);
console.log(b);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<pre id="out"></pre>
如果您使用 lodash
而不是 underscore
,它会提供进一步的改进。
没有underscore.js,使用普通 ES
Step1 : 过滤数组大于1 children
Step2 : 克隆数组,避免不需要的突变。使用 map 函数 return 按 key1 对 child 数组进行升序排序 return 第一个元素
array.filter((a,n)=>{ return a.length>1; })
.map((i)=>{
var a = i.slice(0);
return a.sort((a,b)=>{ return a.key1 > b.key1 })[0];
});
使用underscore.js
var resultArray = _.map(_.filter(arr,(a,n)=>{
return a.length>1;
}),(i)=>{
var a = i.slice(0);
return a.sort(function(a,b){ return a.key1 > b.key1 })[0];
});
这是根据 OP 要求使用 undersore/lodash 的答案:
var array = [
[{
key1: 1,
key2: 'thing'
}, {
key1: 3,
key2: 'thing'
}],
[{
key1: 4,
key2: 'stuff'
}, {
key1: 2,
key2: 'stuff'
}],
[{
key1: 3,
key2: 'onlyOne'
}]
];
array = _.filter(array, function(v) {
return v.length >= 2;
});
array = _.map(array, function(v) {
v.sort(function(a, b) {
return a.key1 > b.key1;
});
return [v[0]];
});
console.log(array);
第二种方法,我们将 map 和 filter 函数合并到一个语句中。接下来有点混乱。
var array = [
[{
key1: 1,
key2: 'thing'
}, {
key1: 3,
key2: 'thing'
}],
[{
key1: 4,
key2: 'stuff'
}, {
key1: 2,
key2: 'stuff'
}],
[{
key1: 3,
key2: 'onlyOne'
}]
];
array = _.map(_.filter(array, function(v) {
return v.length >= 2;
}), function(v) {
v.sort(function(a, b) {
return a.key1 > b.key1;
});
return [v[0]];
});
console.log(array);
输出:
我有以下数组:
var array = [[{key1: 1, key2: thing}, {key1: 3, key2: thing}],
[{key1: 4, key2: stuff}, {key1: 2, key2: stuff}],
[{key1: 3, key2: onlyOne}]]
我需要取出所有少于两个对象的数组,每个剩余的数组可能有 'n' 个对象应该只包含具有最小 key1 的对象。最后我会:
var updatedArray = [[{key1: 1, key2: thing}],[{key1: 2, key2: stuff}]]
我怎样才能使用 Underscore 得到这个?
现在我已经完成了:
var soFar = _.filter(_.groupBy(_.map(array, function(n){return _.find(n)}),
"key2"), function(n){return n.length > 1});
//soFar = [[{key1: 1, key2: thing}, {key1: 3, key2: thing}],
//[{key1: 4, key2: stuff}, {key1: 2, key2: stuff}]]`
这让我摆脱了只有一个对象的数组,但我无法根据对象的比较找出下一部分来修改每个数组。
看来你把事情复杂化了。这是一个纯 ES5 示例,但很容易转换为 underscore
' 语法。
var thing = 'thing';
var stuff = 'stuff';
var onlyOne = 'onlyOne';
var array = [
[{
key1: 1,
key2: thing
}, {
key1: 3,
key2: thing
}],
[{
key1: 4,
key2: stuff
}, {
key1: 2,
key2: stuff
}],
[{
key1: 3,
key2: onlyOne
}]
];
var b = array.filter(function(item) {
return item.length > 1;
}).map(function(item) {
return [item.slice().sort(function(x, y) {
return x.key1 - y.key1;
}).shift()];
});
document.getElementById('out').textContent = JSON.stringify(b, null, 2);
console.log(b);
<pre id="out"></pre>
下划线
var thing = 'thing';
var stuff = 'stuff';
var onlyOne = 'onlyOne';
var array = [
[{
key1: 1,
key2: thing
}, {
key1: 3,
key2: thing
}],
[{
key1: 4,
key2: stuff
}, {
key1: 2,
key2: stuff
}],
[{
key1: 3,
key2: onlyOne
}]
];
var b = _.chain(array).filter(function(item) {
return item.length > 1;
}).map(function(item) {
return [_.chain(item).map(_.identity).sortBy('key1').first()];
});
document.getElementById('out').textContent = JSON.stringify(b, null, 2);
console.log(b);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<pre id="out"></pre>
或者您可以使用 reduce
而不是 filter
和 map
并为自己保存一个循环以及 chain
包装器。
var thing = 'thing';
var stuff = 'stuff';
var onlyOne = 'onlyOne';
var array = [
[{
key1: 1,
key2: thing
}, {
key1: 3,
key2: thing
}],
[{
key1: 4,
key2: stuff
}, {
key1: 2,
key2: stuff
}],
[{
key1: 3,
key2: onlyOne
}]
];
var b = _.reduce(array, function(acc, item) {
if (item.length > 1) {
acc.push([_.chain(item).map(_.identity).sortBy('key1').first()]);
}
return acc;
}, []);
document.getElementById('out').textContent = JSON.stringify(b, null, 2);
console.log(b);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<pre id="out"></pre>
而不是 slice
(或 map
)和 sort
(或 sortBy
),您可以使用 min
并进一步减少 chain
var thing = 'thing';
var stuff = 'stuff';
var onlyOne = 'onlyOne';
var array = [
[{
key1: 1,
key2: thing
}, {
key1: 3,
key2: thing
}],
[{
key1: 4,
key2: stuff
}, {
key1: 2,
key2: stuff
}],
[{
key1: 3,
key2: onlyOne
}]
];
var b = _.reduce(array, function(acc, item) {
if (item.length > 1) {
acc.push([_.min(item, 'key1')]);
}
return acc;
}, []);
document.getElementById('out').textContent = JSON.stringify(b, null, 2);
console.log(b);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<pre id="out"></pre>
如果您使用 lodash
而不是 underscore
,它会提供进一步的改进。
没有underscore.js,使用普通 ES
Step1 : 过滤数组大于1 children
Step2 : 克隆数组,避免不需要的突变。使用 map 函数 return 按 key1 对 child 数组进行升序排序 return 第一个元素
array.filter((a,n)=>{ return a.length>1; })
.map((i)=>{
var a = i.slice(0);
return a.sort((a,b)=>{ return a.key1 > b.key1 })[0];
});
使用underscore.js
var resultArray = _.map(_.filter(arr,(a,n)=>{
return a.length>1;
}),(i)=>{
var a = i.slice(0);
return a.sort(function(a,b){ return a.key1 > b.key1 })[0];
});
这是根据 OP 要求使用 undersore/lodash 的答案:
var array = [
[{
key1: 1,
key2: 'thing'
}, {
key1: 3,
key2: 'thing'
}],
[{
key1: 4,
key2: 'stuff'
}, {
key1: 2,
key2: 'stuff'
}],
[{
key1: 3,
key2: 'onlyOne'
}]
];
array = _.filter(array, function(v) {
return v.length >= 2;
});
array = _.map(array, function(v) {
v.sort(function(a, b) {
return a.key1 > b.key1;
});
return [v[0]];
});
console.log(array);
第二种方法,我们将 map 和 filter 函数合并到一个语句中。接下来有点混乱。
var array = [
[{
key1: 1,
key2: 'thing'
}, {
key1: 3,
key2: 'thing'
}],
[{
key1: 4,
key2: 'stuff'
}, {
key1: 2,
key2: 'stuff'
}],
[{
key1: 3,
key2: 'onlyOne'
}]
];
array = _.map(_.filter(array, function(v) {
return v.length >= 2;
}), function(v) {
v.sort(function(a, b) {
return a.key1 > b.key1;
});
return [v[0]];
});
console.log(array);
输出: