在字符串或数字中搜索字符串或数字

发布于 2025-01-19 15:02:12 字数 1339 浏览 0 评论 0原文

我正在尝试实现对具有多个键/值对的对象的搜索,这些键/值对可以是字符串数字

这就是我目前正在使用的(当然是简化的):

const input = 'Hello WORld 21';   // this could also be of type number
const search = 'O w';   // this could also be of type number
let result = true;
let startTime, endTime;
const t0 = performance.now();
for (let i = 0; i < 1000000; i++) {
    let parsedInput = JSON.stringify(input).toLowerCase().replace(/(^"|"$)/g, '');
    let parsedSearch = JSON.stringify(search).toLowerCase().replace(/(^"|"$)/g, '');
    result = parsedInput.indexOf(parsedSearch);
}
const t1 = performance.now();
console.log(`Call to doSomething took ${t1 - t0} milliseconds with result = ${result}`);
// ~393ms on a Ryzen 5600X

所以这可行,但似乎很昂贵,特别是当我浏览数万个对象(甚至更多)时。所以我想知道是否有一种更优雅的方式来实现这样的搜索。

先感谢您!

编辑:根据 Sergio J 的回答,这是我现在得到的:

const t2 = performance.now();
let i, s;
for (let j = 0; j < 1000000; j++) {
    i = isNaN(input) ? input.toLowerCase() : input.toString().toLowerCase();
    s = isNaN(search) ? search.toLowerCase() : search.toString().toLowerCase();
    result = i.indexOf(s);
}
const t3 = performance.now();
console.log(`Call to doSomething took ${t3 - t2} milliseconds with result = ${result}`);
// ~66ms on a Ryzen 5600X

I'm trying to implement a search of an object with multiple key/value pairs that can be either string or number.

This is what I'm currently using (simplified, of course):

const input = 'Hello WORld 21';   // this could also be of type number
const search = 'O w';   // this could also be of type number
let result = true;
let startTime, endTime;
const t0 = performance.now();
for (let i = 0; i < 1000000; i++) {
    let parsedInput = JSON.stringify(input).toLowerCase().replace(/(^"|"$)/g, '');
    let parsedSearch = JSON.stringify(search).toLowerCase().replace(/(^"|"$)/g, '');
    result = parsedInput.indexOf(parsedSearch);
}
const t1 = performance.now();
console.log(`Call to doSomething took ${t1 - t0} milliseconds with result = ${result}`);
// ~393ms on a Ryzen 5600X

So this works, but seems to be expensive, especially when I go through tens of thousands of objects (or even more). So I wonder if there is a more elegant way to implement a search like this.

Thank you in advance!

Edit: Based on Sergio J's answer, here is what I got now:

const t2 = performance.now();
let i, s;
for (let j = 0; j < 1000000; j++) {
    i = isNaN(input) ? input.toLowerCase() : input.toString().toLowerCase();
    s = isNaN(search) ? search.toLowerCase() : search.toString().toLowerCase();
    result = i.indexOf(s);
}
const t3 = performance.now();
console.log(`Call to doSomething took ${t3 - t2} milliseconds with result = ${result}`);
// ~66ms on a Ryzen 5600X

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

锦欢 2025-01-26 15:02:12

您可能不需要JSON.Stringify,只有在输入为数字的情况下(使用isnan())。

这里有一些帖子谈论不同方法的效率。

javaScript:javascript:indexof vs.搜索字符串时的Indexof vs.找到最适合您的需求和用户的。

这是带有索引版本的代码片段,在功能中提取,检查输入值和搜索值,以便在必要时将其转换为字符串,并告诉您找到的内容。

function stringFinderIndexOf(input, search) {
  let isNumber = !isNaN(input);
  if (isNumber) {
    input = input.toString();
  }

  let isSearchANumber = !isNaN(search);
  if (isSearchANumber) {
    search = search.toString();
  }

  let foundElement = input.toLowerCase().indexOf(search.toLowerCase()) !== -1;

  if (foundElement) {
    let isNumberText = isNumber ? "a numeric value" : "a text";
    console.log("found with indexOf in " + isNumberText);
  }
}

当然,如果您有我了解一个对象,并且要循环循环,则可以使用object.values()和a for循环。

function stringInObjectFinder(input, search) {

  let values = Object.values(input)
  for (const key in values) {
    stringFinderIndexOf(key, search);
  }

}

使用其他方法(如String.Match(Regex))在带有几个函数的沙盒中找到完整的代码。

https://codesandbox.io of -gqijlr?file =/src/index.js

---------加法---------------

编辑:作者建议的清洁剂,如果提取if if if the If总是一个好主意作为具有解释名称的方法。在这种情况下,留下了所有代码来解释自己。

您可以在功能复制的代码中看到(气味)。

function transformToStringIfNecessary(input) {
  let isInputANumber = !isNaN(input);
  if (isInputANumber) {
    input = input.toString();
  }
  return input;
}

function containsInputTheSearchValue(input, search) {
  return input.toLowerCase().indexOf(search.toLowerCase()) !== -1;
}

function stringFinderIndexOf(input, search) {
  let isNumber = !isNaN(input);
  input = transformToStringIfNecessary(input);
  search = transformToStringIfNecessary(search);
  let parsedInput = containsInputTheSearchValue(input, search);
  if (parsedInput) {
    let isNumberText = isNumber ? "a numeric value" : "a text";
    console.log("found with indexOf in " + isNumberText);
  }
}

您可以更清洁代码,但猜猜您明白了。
希望它有帮助。

you may not need that Json.stringify, just toString() in the cases where the input is a number (check with isNaN()).

There are some post here talking about the efficiency of different methods.

JavaScript: indexOf vs. Match when Searching Strings? check the link to find the most suitable for your needs and users.

Here is a code snippet with a indexOf version, extracted in a function, that checks input and search values to convert them to string if necessary, and tells you what has been found.

function stringFinderIndexOf(input, search) {
  let isNumber = !isNaN(input);
  if (isNumber) {
    input = input.toString();
  }

  let isSearchANumber = !isNaN(search);
  if (isSearchANumber) {
    search = search.toString();
  }

  let foundElement = input.toLowerCase().indexOf(search.toLowerCase()) !== -1;

  if (foundElement) {
    let isNumberText = isNumber ? "a numeric value" : "a text";
    console.log("found with indexOf in " + isNumberText);
  }
}

Of course, if you have as I understand an object, and you want to loop through, you could use Object.values() and a for loop.

function stringInObjectFinder(input, search) {

  let values = Object.values(input)
  for (const key in values) {
    stringFinderIndexOf(key, search);
  }

}

Find full code in a sandbox with a couple of functions using other methods as string.match(regex).

https://codesandbox.io/s/focused-chatterjee-gqijlr?file=/src/index.js

-------- Addition --------

Edit: as author suggested cleaner if, it is always a good idea to extract the if as a method with an explanatory name. In this case was left in order to put all code in a function to explain myself.

You can see in the function duplicated code already (smells).

function transformToStringIfNecessary(input) {
  let isInputANumber = !isNaN(input);
  if (isInputANumber) {
    input = input.toString();
  }
  return input;
}

function containsInputTheSearchValue(input, search) {
  return input.toLowerCase().indexOf(search.toLowerCase()) !== -1;
}

function stringFinderIndexOf(input, search) {
  let isNumber = !isNaN(input);
  input = transformToStringIfNecessary(input);
  search = transformToStringIfNecessary(search);
  let parsedInput = containsInputTheSearchValue(input, search);
  if (parsedInput) {
    let isNumberText = isNumber ? "a numeric value" : "a text";
    console.log("found with indexOf in " + isNumberText);
  }
}

You could clean the code even more, but guess you got the point.
Hope it helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文