最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript find object with matching property in array of objects and get another property if exists - Stack Overflow

programmeradmin0浏览0评论

I'm looking for an elegant solution to this the following:

In many places of my code, I need to find an object that matches an id in an array of objects and then return a property on that object. The referenced id may or may not exist in the array.

The shortest solution I have e up with is the following:

(wanting to get the title of an item if the item exists, otherwise return none)

arrayofObjects = [ { id: 'a3ff3d', title: 'Tesla', color: 'Red' }, { id: 'r43wesd', title: 'AMC', color: 'Rust' }]
wantedObject = { queryTitle: 'Desired Car', id: 'a3ff3d' }


let wantedProperty = arrayOfObjects.some( e => e.id === wantedObject.id) ? arrayOfObjects.find(e => e.id === wantedObject.id).title : 'None Found'

However, this is neither elegant or as efficient as it should be. I'd prefer for it to be a one liner instead of a function.

I'm looking for an elegant solution to this the following:

In many places of my code, I need to find an object that matches an id in an array of objects and then return a property on that object. The referenced id may or may not exist in the array.

The shortest solution I have e up with is the following:

(wanting to get the title of an item if the item exists, otherwise return none)

arrayofObjects = [ { id: 'a3ff3d', title: 'Tesla', color: 'Red' }, { id: 'r43wesd', title: 'AMC', color: 'Rust' }]
wantedObject = { queryTitle: 'Desired Car', id: 'a3ff3d' }


let wantedProperty = arrayOfObjects.some( e => e.id === wantedObject.id) ? arrayOfObjects.find(e => e.id === wantedObject.id).title : 'None Found'

However, this is neither elegant or as efficient as it should be. I'd prefer for it to be a one liner instead of a function.

Share Improve this question edited Sep 15, 2021 at 21:03 Sebastian Simon 19.5k8 gold badges61 silver badges84 bronze badges asked Jan 20, 2019 at 22:15 Matt McCallumMatt McCallum 331 silver badge4 bronze badges 13
  • 1 You should provide some sample data and expected result. You should be able to use find once, not some + find. It should return a useful value like undefined or null that other processes can use rather than a random string. – RobG Commented Jan 20, 2019 at 22:18
  • 1 "one-liner" and "efficient" don't really go hand-in-hand a lot of times. You'll always get more performance out of a normal for loop than Array.prototype methods. – Patrick Roberts Commented Jan 20, 2019 at 22:21
  • 1 Just go for (array.find(…) || {}).title – Bergi Commented Jan 20, 2019 at 22:27
  • Example data added. Yes, I am thinking that I should be able to use find once, but I'm struggling on how to write it. Returning undefined or null would be acceptable. – Matt McCallum Commented Jan 20, 2019 at 22:29
  • @PatrickRoberts Not true, native array methods are just as fast as for loops. – Bergi Commented Jan 20, 2019 at 22:29
 |  Show 8 more ments

4 Answers 4

Reset to default 7

The smallest method is not necessarily the most efficient. I would do it this way:

let wantedProperty = (arrayOfObjects.find(obj => obj.id === wantedObject.id) || {}).title || 'None Found';

Use Array#find and destructuring.

const data = [ { id: 'a3ff3d', title: 'Tesla', color: 'Red' }, { id: 'r43wesd', title: 'AMC', color: 'Rust' }];

function search(idToFind){
  const res = data.find(({id}) => id === idToFind);
  return res ? res.title : "Nothing found";
}


console.log(search('r43wesd'));
console.log(search('fail'));

Actually, you can create a one line, generalized method for your data structure that you can reuse multiple times:

const arrayOfObjects = [
    {id: 'a3ff3d', title: 'Tesla', color: 'Red'},
    {id: 'r43wesd', title: 'AMC', color: 'Rust'}
];

const getKey = (a, id, key) => (f = a.find(x => x.id === id)) ? f[[key]] : "Not Found";

console.log(getKey(arrayOfObjects, "a3ff3d", "title"));
console.log(getKey(arrayOfObjects, "r43wesd", "color"));
console.log(getKey(arrayOfObjects, "someid", "color"));

I thought of 2 possible solution. First the one I do NOT remend:

array.reduce((acc, cur) => {
    return cur.id == searchedId ? cur.title : acc;
}, "None found");

Especially if you need to use it frequently, avoid "plex" code, even if we are considering one line.

The second option (if you do not really want to use a function) is this one:

Array.prototype.findOrElse = function(cb, objcb, retValue) {
    let findElem = this.find(elem => cb(elem));

    return objcb(findElem) || retValue;
}

You can call it like this:

array.findOrElse(elem => elem.id == searchedId, elem => elem.title, "None found");

Generally I do not choose this way because I prefer not to touch native objects that js provides, but no one forbids it.


EDIT: As @PatrickRoberts made me notice, this is not really an answer. I just found 2 possible solutions that for different reasons I do not remend. Functions have this advantage: you do not have to repeat the same code, even if it is one line. Think about a possible situation where you may have to retrieve a different property instead of title.

On the other hand, customize a function inside the prototype of Array object is difficult: you try to make that function as generic as possible, with the risk of excessively plicating the function definition.

So why not going with your own defined function?

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论