使数组中的值匹配更快?

时间:2018-08-23 01:41:34

标签: javascript arrays angular performance string-matching

这是我的代码

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  devices = ['x', 'y', 'z'];
  device;
  constructor(public navCtrl: NavController) {
    this.device = 'a';
    for(let i = 0; i<this.devices.length; i++){
      if(this.device == this.devices[i]){
        console.log('Match');
      } else {
        console.log('No matches');
      }
    }
  }
}

我在想,如果我的设备列表过长,则匹配速度将明显变慢。因此,我想问一下是否存在一种更好,更快,更有效的方法来检查数组中是否存在值。

我要实现的是出勤。

我的应用程序将扫描ID,然后检查它是否在我的列表中。 如果匹配,我将布尔值设置为true(出于测试目的) 所说的布尔值将在我的清单上。 像这样

device = {
 name: '-K8d34fsd2',
 attendance: true
};

这就是我尝试过的

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  devices = [
    {
      id: 'qwerty123',
      attendance: false
    },
    {
      id: 'zxcvb123',
      attendance: false
    },
  ];
  device;
  constructor(public navCtrl: NavController) {
    this.device = 'qwerty123';
    // for(let i = 0; i<this.devices.length; i++){
    //   if(this.device == this.devices[i]){
    //     console.log('Match');
    //   } else {
    //     console.log('No matches');
    //   }
    // }

      if(this.devices.id.indexOf(this.device) > -1){
        console.log('Match');
      } else {
        console.log('No matches');
      }
  }
}

4 个答案:

答案 0 :(得分:2)

您在那里有一些选择。

Array.indexOf()比遍历整个数组并检查每个元素是否与条件匹配要好(slighthly faster using your example on a benchmark)。

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  devices = ['x', 'y', 'z'];
  device;
  constructor(public navCtrl: NavController) {
    this.device = 'a';
    if(this.devices.indexOf(this.device) > -1){
        console.log('Match');
    } else {
        console.log('No matches');
    }

  }
}

如果您可以支持ES2016,则Array.includes()indexOf()see the same benchmark)稍好,并且在语法上更易于阅读。

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  devices = ['x', 'y', 'z'];
  device;
  constructor(public navCtrl: NavController) {
    this.device = 'a';
    if(this.devices.includes(this.device)){
        console.log('Match');
    } else {
        console.log('No matches');
    }

  }
}

编辑:由于OP对原始问题的编辑,我将列出使用对象进行搜索的可能方法:

1-for循环:

var test = [{name:'asdfasafdx', attendance: true}, {name:'fdsafdsay', attendance: true}, {name:'sdfasdfasz', attendance: true}];

var device = {name:'fdwoierqea'};

for(let i = 0; i < test.length; i++){
      if(device.name == test[i].name){
        console.log('Match');
      } else {
        console.log('No matches');
      }
}

2-{{​​1}}(faster

Array.filter()

答案 1 :(得分:2)

由于您要尝试基于特定ID查找项目,因此最快的数组不是数组,而是一个对象:

devices = {
   qwerty123: {attendance: true, otherData: "whatever"}, 
   zxcvb123:  {attendance: false, etcetera: "etcetera"}
}

现在,您的“搜索”只是一个关键的查询:

devices.querty123  // returns {attendance: true, otherData: "whatever"}
devices.notarealkey // returns undefined

// when searching with a variable:
this.device = 'qwerty123';
devices[this.device] // returns the same as devices.querty123

答案 2 :(得分:1)

您可以使用time complexity在O(n)Array.prototype.map()中创建更新的出席者列表。

请参见下面的实际示例。

// Input.
const devices = [{id: 'A', attendance: false}, {id: 'B', attendance: false}, {id: 'C', attendance: false}]
const deviceId = 'B'

// Update Device Attendance.
const updateDeviceAttendance = (devices, deviceId) => devices.map(x => {
  if (x.id == deviceId) return {...x, attendance: true}
  return x
})

// Ouput + Proof.
const output = updateDeviceAttendance(devices, deviceId)
console.log(output)

尽管,O(1)时间复杂度可以使用对象而不是数组来实现。

// Input.
const devices = {'A': {attendance: false}, 'B': {attendance: false}, 'C': {attendance: false}}
const deviceId = 'B'

// Update Device Attendance.
const updateDeviceAttendance = (devices, id) => ({...devices, [id]: {id, attendance: true}})

// Ouput + Proof.
const output = updateDeviceAttendance(devices, deviceId)
console.log(output)

答案 3 :(得分:0)

尽管这个社区的乐于助人的人打字并提交了答案,但我还是试图找到一个能做出贡献的人。

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  devices = [
    {
      id: 'qwerty123',
      attendance: false
    },
    {
      id: 'zxcvb123',
      attendance: false
    },
  ];
  device;
  constructor(public navCtrl: NavController) {
    this.device = 'qwerty123';

    let result = this.devices.find( device => device.id === this.device);
    console.log(result);
  }
}

find方法返回所请求的对象,如果没有,则返回未定义的对象。 至于速度,我还没有测试过。我以为别人也想知道。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find