在数组对象内部过滤数组后返回值

时间:2018-09-21 10:19:51

标签: javascript angular ecmascript-6 functional-programming

我正在尝试创建一个自动完成功能,该功能使用函数返回对象数组。我的对象类似于:

this.vehiclesList =
  [
    {
      "additionalDriverContacts": [9929929929, 9992992933, 9873773777],
      "id": 1
    },
    {
      "additionalDriverContacts": [8388388388, 8939939999],
      "id": 2
    }
  ]

我想基于 additionalDriverContacts 过滤数组。

我的功能如下:

filterVehicleAdditionalMobile(val: string) {
     if (typeof val != 'string') {
            return [];
        }
    let value= val? this.vehiclesList.filter((item) => {
            if(item.additionalDriverContacts) 
                 item.additionalDriverContacts.forEach((option)=> {
                   String(option).toLowerCase().indexOf(val.toLowerCase()) != -1 
                })
             }
     }) : this.vehiclesList;
    console.log(value)
    return value;
}

但是在控制台中,值是空数组。我哪里做错了。我尝试在此问题How do i filter an array inside of a array of objects?中寻找解决方案 但这并没有帮助,因为我的用例有所不同。

我想要的结果应为: 如果将99299作为参数传递给该函数,则匹配该数字的AdditionalDriverContacts应该作为数组返回。 对于输入99299,应返回结果= [9929929929,9992992933]

3 个答案:

答案 0 :(得分:1)

  

对于输入99299,应返回结果= [9929929929,9992992933]

我们可以使用数组.map()提取联系人,然后使用字符串.search()进行过滤:

const vehiclesList = [
    {"id": 1, "additionalDriverContacts": [9929929929, 9992992933, 9873773777]},
    {"id": 2, "additionalDriverContacts": [8388388388, 8939939999]}]

result = getMatchingContacts(vehiclesList, 99299) // run test
console.log(result)                               // show result

function getMatchingContacts(list, key) {  
  const arrayOfContacts = list.map(item => item.additionalDriverContacts)
  const contacts = [].concat(...arrayOfContacts)                       // flatten the nested array
    .filter(contact => contact.toString().search(key.toString()) >= 0) // find matches
  return contacts
}

希望这会有所帮助。

干杯

答案 1 :(得分:0)

已更新:问题的最后修改

尝试通过以下方式进行更改:

  filterVehicleAdditionalMobile(val: string) {
    if (typeof val !== 'string') {
      return [];
    }

    let driverContacts = [];
    this.vehiclesList.forEach((vehicule) => {
      if (vehicule.additionalDriverContacts) {
        if (val) {
          driverContacts = driverContacts.concat(vehicule.additionalDriverContacts.filter((driverContact) => {
            return String(driverContact).toLowerCase().indexOf(val.toLowerCase()) !== -1;
          }));
        } else {
          driverContacts = driverContacts.concat(vehicule.additionalDriverContacts);
        }
      }
    });

    return driverContacts;
  }

测试:

const driver = this.filterVehicleAdditionalMobile('8');
console.log(driver);

显示:

0:9873773777 1:8388388388 2:8939939999

答案 2 :(得分:0)

因此,您需要在这里首先将vehiclesList中的每个项目转换成匹配结果的数组,然后将它们连接在一起。

尝试一下:

var vehiclesList = [{
    "additionalDriverContacts": [9929929929, 9992992933, 9873773777],
    "id": 1
  },
  {
    "additionalDriverContacts": [8388388388, 8939939999],
    "id": 2
  }
];

function filterVehicleAdditionalMobile(val) {
  if (typeof val != 'string') {
    return [];
  }
  // array of arrays
  const values = vehiclesList.map((item) => {
      if (!item.additionalDriverContacts) { return []; }
      
      return item.additionalDriverContacts.filter((option) => 
          String(option).toLowerCase().indexOf(val.toLowerCase()) != -1
      );
  });
  
  console.log(values);

  // flatten
  return Array.prototype.concat.apply([], values);
}

console.log(filterVehicleAdditionalMobile('99'));

或者,您可以将所有项目串联在一起,然后过滤它们。这样效率较低,但是代码更简单,更少:

var vehiclesList = [{
    "additionalDriverContacts": [9929929929, 9992992933, 9873773777],
    "id": 1
  },
  {
    "additionalDriverContacts": [8388388388, 8939939999],
    "id": 2
  }
];

function flatten(values) {
    return Array.prototype.concat.apply([], values);
}

function filterVehicleAdditionalMobile(val) {
  if (typeof val != 'string') {
    return [];
  }
  
  return flatten(vehiclesList.map(v => v.additionalDriverContacts || []))
      .filter(option => String(option).toLowerCase().indexOf(val.toLowerCase()) != -1);
}

console.log(filterVehicleAdditionalMobile('99'));