我怎么能在 javascript 中得到不匹配的字符串?
How could i get Not matched String in javascript?
我有一个预订数组,我必须使用 searchValue
在数组内搜索。
这里我们必须检查预订 ID 字段。如果预订 ID 和 searchValue
匹配,我们必须将该对象推入结果数组。
工作代码
结果数组示例如下
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"
您可以尝试这样的操作:
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
的这个数值之前生成的。然后只需要从 变异的 set
和 join
它的 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}`));
我有一个预订数组,我必须使用 searchValue
在数组内搜索。
这里我们必须检查预订 ID 字段。如果预订 ID 和 searchValue
匹配,我们必须将该对象推入结果数组。
工作代码
结果数组示例如下
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"
您可以尝试这样的操作:
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
的这个数值之前生成的。然后只需要从 变异的 set
和 join
它的 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}`));