Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
72 views
in Technique[技术] by (71.8m points)

javascript - How to faster search an array of objects?

I am trying to find a better way to search an array of objects as my current method is much too slow. I have an array that looks like this:

[
  {
    fname: 'r7942y9p',
    lname: 'gk0uxh',
    email: 'afit9og@gmail.com',
    phone: 2326571226
  },
  {
    fname: 'hipnr9f6',
    lname: 'rsnse5',
    email: 'ryv47qi@gmail.com',
    phone: 7863302156
  },
...

I want to search its objects by email and phone and return the first object that has a given phone OR email.

Question: Is there a faster way than

const log = data.find(item => {
    return (item.email && item.email === email) || (item.phone && item.phone === phone)
});

I have put together this simple benchmark:

const data = [];
let r = len => Math.random().toString(36).substring(len);
let n = (min, max) => Math.round(Math.random() * (max - min));

for(let i = 0; i < 50000; i++){
    data.push(
        {
            fname: r(5),
            lname: r(7),
            email: `${r(6)}@gmail.com`,
            phone: n(10000000000, 20000000000)
        }
    )
}

const email = 'sdklhfldkf@gmail.com', phone = 19027931232;

console.time('search_time');
const log = data.find(item => {
    return (item.email && item.email === email) || (item.phone && item.phone === phone)
});
console.timeEnd('search_time')
console.log(log ? 'Found':'Not Found')
question from:https://stackoverflow.com/questions/65621754/how-to-faster-search-an-array-of-objects

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you're ok with preprocessing and using about the same amount of memory as data again, consider precomputing a lookup object (e.g. an index).

// Use lodash
const emailIndex = _.invertBy(data, 'email')
const phoneIndex = _.invertBy(data, 'phone')

Indexing is about 40 times slower than searching with your method.

Here is your benchmark again:

const data = [];
let r = len => Math.random().toString(36).substring(len);
let n = (min, max) => Math.round(Math.random() * (max - min));

for (let i = 0; i < 50000; i++) {
    data.push(
        {
            fname: r(5),
            lname: r(7),
            email: `${r(6)}@gmail.com`,
            phone: n(10000000000, 20000000000)
        }
    )
}

const email = 'sdklhfldkf@gmail.com', phone = 19027931232;

console.time('indexing_time');
const emailIndex = _.invertBy(data, 'email')
const phoneIndex = _.invertBy(data, 'phone')
console.timeEnd('indexing_time')


console.time('search_time');
const log = emailIndex[email] || phoneIndex[phone]
console.timeEnd('search_time')
console.log(log ? 'Found' : 'Not Found')
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...