在对象数组中根据多个值进行搜索

5

我有一个对象数组:

[
  {
    "caseNumber": 123,
    "patientName": "John Doe",
    "technician": "Jasmin Joe",
    "reader": "Jade Boe"
  },
  {
    "caseNumber": 123,
    "patientName": "John Doe",
    "technician": "Jasmin Joe",
    "reader": "Jade Boe"
  },
  {
    "caseNumber": 123,
    "patientName": "John Doe",
    "technician": "Jasmin Joe",
    "reader": "Jade Boe"
  }
]

我在顶部有一个搜索栏,想要从我提供的任何密钥中搜索匹配的字符串。例如:我想从caseNumber、patientName和reader中进行搜索,因此我会调用我的过滤函数filter(allCases, caseNumber, patientName, reader)。
我尝试使用Angular管道,但它只适用于前两个键。我尝试了以下代码:
this.activeCases = this.filterPipe.transform(
      activeCases,
      this.searchUser,
      this.isCurrentUserTech ? 'readerName' : 'techName',
      'patientFullName',
      'caseNumber'
    );

而我的管道函数:

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {
  transform(items: any[], value: string, label: string, optionalLabel?: string, optionalLabel2?: string, optionalValue?: string): any[] {
    if (!items) {
      return [];
    }
    if (!optionalValue && !value) {
      return items;
    }

    if ((value === '' || value == null) && (optionalValue === '' || optionalValue == null)) {
      return [];
    }

    if (optionalValue && optionalLabel) {
      this.filterByValue(value, items, label, optionalLabel, optionalValue);
    } else if (optionalLabel) {
      return items.filter(e => (e[optionalLabel] + ', ' + e[label]).toLowerCase().indexOf(value.toLowerCase()) > -1);
    } else if (optionalLabel && label && value) {
      return items.filter(item => {
        let object: any = { item1: optionalLabel, item2: label };
        if (optionalLabel2) {
          object = { item1: optionalLabel, item2: label, item3: optionalLabel2 };
        }
        for (const property in object) {
          if (item[object[property]] === null) {
            continue;
          }
          if (item[object[property]].toString().toLowerCase().includes(value.toLowerCase())) {
            return true;
          }
        }
        return false;
      });
    } else {
      return items.filter(e => {
        const tempValue = e[label] ? e[label].toLowerCase() : '';
        return tempValue.indexOf(value.toLowerCase()) > -1;
      });
    }
  }

  filterByValue(value, items, label, optionalLabel, optionalValue) {
    if (value) {
      return items.filter(e => {
        const firstLabel = e[label] ? e[label].toLowerCase() : '';
        const secondLabel = e[optionalLabel] ? e[optionalLabel].toLowerCase() : '';
        const firstValue = value ? value.toLowerCase() : value;
        const secondValue = optionalValue ? optionalValue.toLowerCase() : optionalValue;
        let firstCheck = false;
        let secondCheck = false;
        if (firstLabel && firstValue) {
          firstCheck = firstLabel.includes(firstValue);
        }
        if (secondLabel && secondValue) {
          secondCheck = secondLabel.includes(secondValue);
        }
        return firstCheck && secondCheck;
      });
    } else {
      return items.filter(e => {
        const tempValue = e[optionalLabel] ? e[optionalLabel].toLowerCase() : '';
        return tempValue.indexOf(optionalValue.toLowerCase()) > -1;
      });
    }
  }
}

我错过了什么? 我也可以使用lodash。

2个回答

3

const data = [{
    caseNumber: 123,
    patientName: 'Adam',
    technician: 'Jasicca',
    reader: 'Potter',
  },
  {
    caseNumber: 456,
    patientName: 'John Doe',
    technician: 'Kevin',
    reader: 'Harry',
  },
  {
    caseNumber: 789,
    patientName: 'Ram',
    technician: 'Bob',
    reader: 'Jade Boe',
  },
];

const input = document.querySelector('input');
const log = document.getElementById('log');

function searchArray(e) {
  let filtered = [];
  const input = e.target.value.toLowerCase();
  if (input) {
    filtered = data.filter((el) => {
      return Object.values(el).some((val) =>
        String(val).toLowerCase().includes(input)
      );
    });

    log.textContent = JSON.stringify(filtered);
  }
}
<input placeholder="Enter some text" name="name" onkeyup="searchArray(event)" />
<p id="log"></p>


2
您可以使用一个搜索对象,例如{ patientName: 'John', technician: 'Jasmin' },并将其提供给findResults函数。
我们将使用Array.filterArray.every来确保满足所有搜索条件。
如果您希望结果显示任何搜索条件,则可以使用Array.some而不是Array.every。
类似于:

let arr = [
  {
    "caseNumber": 123,
    "patientName": "John Doe",
    "technician": "Jasmin Joe",
    "reader": "Jade Boe"
  },
  {
    "caseNumber": 456,
    "patientName": "John Doe",
    "technician": "Jasmin Joe",
    "reader": "Jade Boe"
  },
  {
    "caseNumber": 789,
    "patientName": "Jim Doe",
    "technician": "Jasmin Joe",
    "reader": "Jade Boe"
  }
];

// Customize as appropriate.
// Currently performs a case-insensitive match
function searchMatch(target, search) {
    search = String(search).trim().toLowerCase();
    return String(target).toLowerCase().includes(search);
}

function findResults(arr, searchObj) {
    return arr.filter(el => { 
        return Object.entries(searchObj).every(([key, value]) => searchMatch(el[key], value));
    })
}

console.log("Result 1:", findResults(arr, { patientName: 'JIM'}));
console.log("Result 2:", findResults(arr, { patientName: 'John Doe'}));
console.log("Result 3:", findResults(arr, { patientName: 'jim doe', technician: 'jasmin'}));
console.log("Result 4:", findResults(arr, { caseNumber: '123' }));
console.log("Result 5:", findResults(arr, { technician: 'Mark Johnson' }));

 


更通用的解决方案 - ikhvjs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接