我怎么能在 javascript 中得到不匹配的字符串?

How could i get Not matched String in javascript?

我有一个预订数组,我必须使用 searchValue 在数组内搜索。

这里我们必须检查预订 ID 字段。如果预订 ID 和 searchValue 匹配,我们必须将该对象推入结果数组。

工作代码

  1. 结果数组示例如下

    let searchValue = "12,13,15"

结果:

[{ name:"user 3", bookingid:12, product: "ui" },
    { name:"user 4", bookingid:13, product: "ef" }]

预期输出:

12,13 在预订数组中匹配,所以我们必须得到 NotMatchedsearchValue = "15" 你能帮忙吗

let bookingArr = [
    { name:"user 1", bookingid:10, product: "ab" },
    { name:"user 1", bookingid:10, product: "cd" },

    { name:"user 2", bookingid:11, product: "ui" },
    { name:"user 1", bookingid:10, product: "ef" },

    { name:"user 3", bookingid:12, product: "ui" },
    { name:"user 4", bookingid:13, product: "ef" },
];
let searchValue = "12,13,15";
let set = new Set(searchValue.split(",").map(Number)); // for faster lookup
let res = bookingArr.filter(x => set.has(x.bookingid));
console.log(res);

// how can i get not matched searchValue 
// expected result notmatchedsearchValue ="15"

demo

您可以尝试这样的操作:

for (let result of res) {
    set.delete(result.bookingid);
}

然后,set 将仅包含未返回的值——在本例中,仅包含 15.

如果你想保留 set 中的值,你也可以用 let nset = new Set(set); 之类的东西克隆集合,然后用 nset 代替 set在 for 循环中。

如果你想要一条线,灵感来自@Barmar:

[...set].filter(x => !res.some(y => y.bookingid == x)).join(",");

这里的情况和你之前的不一样。所以,在这里你需要从 bookingArr 而不是 searchVal.

中创建一个 Set

let bookingArr = [
  { name: "user 1", bookingid: 10, product: "ab" },
  { name: "user 1", bookingid: 10, product: "cd" },

  { name: "user 2", bookingid: 11, product: "ui" },
  { name: "user 1", bookingid: 10, product: "ef" },

  { name: "user 3", bookingid: 12, product: "ui" },
  { name: "user 4", bookingid: 13, product: "ef" },
];

let searchValue = "12,13,15";
let set = new Set(bookingArr.map((b) => b.bookingid));
let res = searchValue
  .split(",")
  .map(Number)
  .filter((s) => !set.has(s))
  .join();
console.log(res);

OP 快到了。因为 对于每个 数组项的 bookingid 必须 delete 来自 set 的这个数值之前生成的。然后只需要从 变异的 setjoin 它的 items/values 再次创建一个 数组为了获得最终的字符串值结果。

OP 的代码有一些小改动...

let bookingArr = [
    { name:"user 1", bookingid:10, product: "ab" },
    { name:"user 1", bookingid:10, product: "cd" },

    { name:"user 2", bookingid:11, product: "ui" },
    { name:"user 1", bookingid:10, product: "ef" },

    { name:"user 3", bookingid:12, product: "ui" },
    { name:"user 4", bookingid:13, product: "ef" },
];
let searchValue = '12,13,15';

let set = new Set(searchValue.split(',').map(Number)); // for faster lookup

bookingArr.forEach(item => set.delete(item.bookingid));

let notmatchedSearchValue = Array.from(set).join(',');

console.log({ searchValue, notmatchedSearchValue });
// expected result notmatchedsearchValue = '15'
.as-console-wrapper { min-height: 100%!important; top: 0; }

一种更通用的方法是实现一个缩减器函数,具有一个与数组项 属性 名称无关的过滤过程。这个 reducer 也确实同时完成了这两个任务,通过自定义 属性-name(key) 过滤数组项并提供缺失(不匹配)值的最终字符串值......类似...

function collectMatchingItemAndMissingValue(collector, item) {
  const { key, searchValues, missingValues, matchingItems } = collector;
  const value = item[key];

  if (searchValues.has(value)) {

    matchingItems.push(item);
    missingValues.delete(value);    
  }
  return collector;
}

function getMatchingItemsAndMissingValues(arr, key, searchValues, castValue) {
  searchValues = new Set(
    searchValues.split(',').map(castValue)
  );
  const {
    missingValues,
    matchingItems,
  } = arr.reduce(collectMatchingItemAndMissingValue, {
    key,
    searchValues,
    missingValues: new Set([...searchValues]),
    matchingItems: [],
  });
  return {
    matchingItems,
    missingValues: [...missingValues].join(', '),
  };
}

const bookingArr = [
  { name:"user 1", bookingid:10, product: "ab" },
  { name:"user 1", bookingid:10, product: "cd" },
  { name:"user 2", bookingid:11, product: "ui" },
  { name:"user 1", bookingid:10, product: "ef" },
  { name:"user 3", bookingid:12, product: "ui" },
  { name:"user 4", bookingid:13, product: "ef" },
];
const searchValues = '12, 13, 15';
const castValue = str => Number(str.trim());
const {

  matchingItems,
  missingValues,

} = getMatchingItemsAndMissingValues(bookingArr, 'bookingid', searchValues, castValue);

console.log({ matchingItems, missingValues, searchValues });

console.log({
  ...getMatchingItemsAndMissingValues(
    bookingArr,
    'product',
    'xy, ui, mn, qr, ef',
    str => str.trim(),
  ),
  searchValues: 'xy, ui, mn, qr, ef'
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

如果您可以将新集合的浅表副本制作为数组,我们可以使用数组 some() 方法并使用 ! 否定它以从该集合中查找任何 ID bookingArr.

中不存在的

let bookingArr = [
    { name:"user 1", bookingid:10, product: "ab" },
    { name:"user 1", bookingid:10, product: "cd" },

    { name:"user 2", bookingid:11, product: "ui" },
    { name:"user 1", bookingid:10, product: "ef" },

    { name:"user 3", bookingid:12, product: "ui" },
    { name:"user 4", bookingid:13, product: "ef" },
];
let searchValue = "12,13,15";
let set = new Set(searchValue.split(",").map(Number)); // for faster lookup
let res = bookingArr.filter(x => set.has(x.bookingid));
// console.log(res);
let notMatchedSearchValues = [...set].filter(y => !bookingArr.some(x => y === x.bookingid));

notMatchedSearchValues.forEach(id => console.log(`notMatchedSearchValue: ${id}`));