最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - use the filter and match methods on an array to find exact matches - Stack Overflow

programmeradmin2浏览0评论

I'm using a filter function to find JSON objects in an array called arrayList, which contains for example:

[
 {
   "name": "Markdown",
   "extension": "(.md)"
 },
 {
   "name": "MultiMarkdown",
   "extension": "(.mmd, .txt)"
 }
]

I'm using the following code to search on the name field and find a match for an object with a certain name:

findFormat = (name) => {
  let format = arrayList.filter(function (el) {
    let pattern = new RegExp(name);
    return el.name.match(pattern);
  });
  return format.name
}

So if I'm searching for an object that has the name "Markdown" then this string gets passed via the name parameter in the function above, and the RegExp expression resolves to /Markdown/.

For the filter function itself, I've implemented the polyfill described at the bottom of the MDN documentation:

if (!Array.prototype.filter)
        Array.prototype.filter = function(func, thisArg) {
            'use strict';
            if ( ! ((typeof func === 'Function') && this) )
                throw new TypeError();

            var len = this.length >>> 0,
                res = new Array(len), // preallocate array
                c = 0, i = -1;
            if (thisArg === undefined)
                while (++i !== len)
                    // checks to see if the key was set
                    if (i in this)
                        if (func(t[i], i, t))
                            res[c++] = t[i];
                        else
                            while (++i !== len)
                                // checks to see if the key was set
                                if (i in this)
                                    if (func.call(thisArg, t[i], i, t))
                                        res[c++] = t[i];

            res.length = c; // shrink down array to proper size
            return res;
        };

For the regular expression I'm not using any special flags like i because I want to find an exact match for "Markdown". However it keeps returning instead MultiMarkdown. I had thought that the filter function above found only exact matches, and not substrings.

Question: is there a way I can filter for only exact matches, using the filter and match methods? Wouldn't the polyfill above return an exact match?

I'm using a filter function to find JSON objects in an array called arrayList, which contains for example:

[
 {
   "name": "Markdown",
   "extension": "(.md)"
 },
 {
   "name": "MultiMarkdown",
   "extension": "(.mmd, .txt)"
 }
]

I'm using the following code to search on the name field and find a match for an object with a certain name:

findFormat = (name) => {
  let format = arrayList.filter(function (el) {
    let pattern = new RegExp(name);
    return el.name.match(pattern);
  });
  return format.name
}

So if I'm searching for an object that has the name "Markdown" then this string gets passed via the name parameter in the function above, and the RegExp expression resolves to /Markdown/.

For the filter function itself, I've implemented the polyfill described at the bottom of the MDN documentation:

if (!Array.prototype.filter)
        Array.prototype.filter = function(func, thisArg) {
            'use strict';
            if ( ! ((typeof func === 'Function') && this) )
                throw new TypeError();

            var len = this.length >>> 0,
                res = new Array(len), // preallocate array
                c = 0, i = -1;
            if (thisArg === undefined)
                while (++i !== len)
                    // checks to see if the key was set
                    if (i in this)
                        if (func(t[i], i, t))
                            res[c++] = t[i];
                        else
                            while (++i !== len)
                                // checks to see if the key was set
                                if (i in this)
                                    if (func.call(thisArg, t[i], i, t))
                                        res[c++] = t[i];

            res.length = c; // shrink down array to proper size
            return res;
        };

For the regular expression I'm not using any special flags like i because I want to find an exact match for "Markdown". However it keeps returning instead MultiMarkdown. I had thought that the filter function above found only exact matches, and not substrings.

Question: is there a way I can filter for only exact matches, using the filter and match methods? Wouldn't the polyfill above return an exact match?

Share Improve this question asked Nov 5, 2017 at 19:42 orlando21orlando21 3071 gold badge5 silver badges18 bronze badges 3
  • 1 There's no such thing as a "JSON object". JSON is a string format. – Scott Marcus Commented Nov 5, 2017 at 19:43
  • You should review what .match actually does. – melpomene Commented Nov 5, 2017 at 19:49
  • @ScottMarcus w3schools./js/js_json_objects.asp – orlando21 Commented Nov 6, 2017 at 6:42
Add a ment  | 

3 Answers 3

Reset to default 8

There's a few misunderstandings you have:

  1. Regular expressions is used for matching strings that match a certain pattern. It's a powerful thing but I'd say it's not the best tool to use if you're trying to find an exact match. In that case, you could just use the strict equality operator ===. (If you did want to use regex, you could add the ^ and the $ before the regex to match the first and last characters of the line e.g. /^Markdown$/ would only match Markdown)
  2. Polyfills implement missing features of the Javascript standard (EcmaScript) and Array.prototype.filter is implemented in all major browsers do you don't need to implement it.

See the example below on how to match name strictly.

const array = [{
    "name": "Markdown",
    "extension": "(.md)"
  },
  {
    "name": "MultiMarkdown",
    "extension": "(.mmd, .txt)"
  }
]

const criteria = 'Markdown';

const result = array.filter(item => item.name === criteria);

console.log('result', result);

You don't need RegEx here and probably shouldn't use it as it will be slower. However, that is not the issue. The issue is that new RegExp(name); will create a RegEx that does a contains search. See https://developer.mozilla/en-US/docs/Web/JavaScript/Guide/Regular_Expressions.

I would remend changing

let pattern = new RegExp(name);
return el.name.match(pattern);

to

return el.name === name;

Check for equality if you want exact match

  let format = arrayList.filter(function (el) {    
    return el.name === name;
  });

Or if you want case insensitive then normalize the cases:

  let format = arrayList.filter(function (el) {    
    return el.name.toLowerCase() === name.toLowerCase();
  });
发布评论

评论列表(0)

  1. 暂无评论