正如标题所说,我试图在找到之后安全地获得对象的属性。
让我们假设我有这样的数组:
var ppl = [
{ id: 1, name: 'Smith' },
{ id: 2, name: 'Wesson' },
{ id: 3, name: 'Remington' },
{ id: 4, name: 'Colt' }
];
所以我试图通过id来获得这位尊敬的绅士之一的名字,所以我使用_.find
。
var person = _.find(ppl, function(p) { return p.id === 2; });
我正在寻找一种安全获取name
链中_
的方法。类似的东西:
var personName = _.chain(ppl)
.find(function(p) { return p.id === 2; })
.get('name') //<-- can't find appropriate method :(
.values();
Ofc我可以用if(person&amp;&amp; person.name)这样的支票来做...或者甚至编写我自己的原型方法,但不想重新发明轮子。
答案 0 :(得分:2)
当你使用get
时我假设你使用的是lodash而不是下划线。如果是这样,那么您可以使用版本4.14.0中引入的defaultTo:
var ppl = [
{ id: 1, name: 'Smith' },
{ id: 2, name: 'Wesson' },
{ id: 3, name: 'Remington' },
{ id: 4, name: 'Colt' }
];
var nullPerson = {
id: 0,
name: 'null'
}
var personName = _.chain(ppl)
.find({id: 99})
.defaultTo(nullPerson)
.get('name')
.value();
console.log(personName);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
答案 1 :(得分:2)
我相信GruffBunny是正确的,因为你似乎在使用Lodash而不是Underscore。我也觉得答案中提供的解决方案非常优雅,但我想展示一种替代方案。
注意:我将提供一个Underscore答案,因为问题被标记为Lodash,因为OP似乎对此感兴趣
我总觉得有点尴尬的一件事就是你所处的确切情况 - 链(数组) - &gt;做操作 - &gt;找到 - &gt;做其他事情。 Underscore中的Object函数略有偏差。但是,我们仍然可以尝试这样做:
var ppl = [
{ id: 1, name: 'Smith' },
{ id: 2, name: 'Wesson' },
{ id: 3, name: 'Remington' },
{ id: 4, name: 'Colt' }
];
function findName(id) {
return _.chain(ppl)
.findWhere({id: id}) // <- shorter syntax than _.find and does the same as supplying your own function.
// It's even shorter than the already short fat arrow syntax which would be: (p => p.id === 2)
.pick('name') // <- extract a new object that has a single property "name"
.map() //<- 1. for objects, it's equivalent to mapping the values only, e.g., _.map(_.values(obj))
//^- 2. if no argument is specified, it defaults to _.identity
.first() // <- since the previous step returns an array of one value this step unwraps it and leaves you with a plain value
.value(); // end chain, return result
}
console.log("Find ID = 2:", findName(2));
console.log("Find ID = 42:", findName(42));
console.log('Find ID = "2" (string value):', findName("2"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
&#13;
所以,这将完成这项工作,但有点尴尬。你缺少.get
,所以你必须采摘 - &gt;地图 - &gt;先做相同的事。它并不严格,但它并不是那么好。另一种方法是将单个结果保存在一个数组中,以便运行其他函数。所以,你可以这样做
_.chain(ppl)
.where({id: id}) //it's basically "filterWhere" like _.findWhere but it returns all results in an array. In this case, it would be a single result purely so we can do the below
.map('name') //<- allows you to map by name of the property but only with arrays
.first() // <- still have to unwrap
.value();
让我们看看等效的
Lodash更好一些,因为它的语法更平滑,并且对对象的处理也更好一些,因此您不必面对需要将它们保存在一个值的数组中的情况。
var ppl = [
{ id: 1, name: 'Smith' },
{ id: 2, name: 'Wesson' },
{ id: 3, name: 'Remington' },
{ id: 4, name: 'Colt' }
];
function findName(id, defaultName) {
return _.chain(ppl)
.find({id: id}) //<- Lodash does not have _.findWhere but the normal _.find already handles this
.get('name') // <- see, much simpler! You can also supply a second argument which would be returned as a default value
.value();
}
console.log("Find ID = 2:", findName(2));
console.log("Find ID = 42:", findName(42));
console.log('Find ID = "2" (string value):', findName("2"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
&#13;