谁可以帮助解释这个JavaScript算法[].filter.call()
Who can help to explain this JavaScript algorithm [].filter.call()
我的任务是按字符串作为参数的顺序接收唯一元素。我不明白这个函数 uniqueElements 如何返回['A','B','C','B']
.
var word = "AAAABBBBCCBB";
var uniqueElements = function(word) {
return [].filter.call(word, (function(elem,index) {
return word[index-1] !== elem
}));
}
uniqueElements(word);
//it should return ['A','B','C','B']
我检查并阅读了以下来源:
MDN Mozilla和JS博客,但没有成功。
这里[].filter.call
的目的是在字符串上应用 filter
方法。天真地,你会首先尝试这样做:
return word.filter(function(elem,index) {
return word[index-1] !== elem;
});
。如果word
是一个数组,它将返回其中满足条件word[index-1] !== elem
(word[index-1] !== word[index]
的缩写(的字符,即每个字符都与它前面的字符不同。
但是,filter
方法仅存在于从Array
原型继承的对象上,字符串并非如此。
但是,filter
本身可以处理类似数组的对象,即具有length
并且可能具有数字属性的对象。要在没有真正的Array
对象的情况下调用filter
,可以在该函数上使用call
,然后提供上下文(即类似数组的对象(作为第一个参数。其他参数保持不变。所以你首先需要知道在哪里可以找到filter
方法......它在 Array.prototype
上,所以你会像这样引用它:
Array.prototype.filter
但是由于所有数组都可以访问此方法,因此仅获取一个空数组并引用其filter
方法会更短:
[].filter
两者中的任何一个都可以工作。现在,您必须在其上执行 call
方法,并提供要迭代的类似数组的对象:
[].filter.call(words, ...)
其余的就像你对真数组所做的那样:你提供回调函数:
return [].filter.call(word, function(elem,index) {
return word[index-1] !== elem
});
返回值不再是字符串。它 - 就像filter
总是返回 - 一个数组:一个真实的数组 - 它是由filter
方法创建的。
ES6 方式:
在 ES6 中,你可以用更易读的方式编写它,因为现在有 Array.from
方法,它可以将类似数组的对象转换为真正的数组。然后你可以继续使用filter
方法:
return Array.from(word).filter(function(elem,index) {
return word[index-1] !== elem
});
点差运算符是 ES6 提供的另一种选择:
return [...word].filter(function(elem,index) {
return word[index-1] !== elem
});
var uniqueElements = function(word) {
return [].filter.call(word, (function(elem,index) {
return word[index-1] !== elem
}));
}
相当于
var uniqueElements = function(word) {
return word.split("").filter(function(elem,index) {
return word[index-1] !== elem
});
}
这应该已经更清楚了:它将单词转换为 char 数组,然后过滤与前一个不同的每个字符。这就解释了为什么"B"在结果中出现两次。
要获得独特的元素,您可以这样做
var uniqueElements = function(word) {
var res = []
word.split("").forEach(function(val){
if (res.indexOf(val)===-1) res.push(val);
});
return res
}
它对数组对象的过滤器方法执行显式call()
,以便它们可以传入字符串。他们只是使用[]
而不是Array
因为它的语法较短,或者有人在编写时试图变得聪明。
通常,filter()
方法会影响数组本身的内容。但是,通过call()
-ing 它,您可以通过传入另一个数组或在本例中传递一个字符串(被视为字符数组(来更改上下文。然后,它为每个元素运行提供的函数,如果函数的返回值为 true
,则保留该元素。
如果你不明白代码是做什么的,你可以记录操作!IE
var word = "AAAABBBBCCBB";
function uniqueElements(word){
return [].filter.call(word,(
function(elem,index) {
console.log("Index : "+index+" | Elem : " +elem+" | CompareTo "+word[index-1]);
return word[index-1] !== elem;
}
));
}
uniqueElements(word);
您将获得以下输入:
Index : 0 | Elem : A | CompareTo undefined
Index : 1 | Elem : A | CompareTo A
Index : 2 | Elem : A | CompareTo A
Index : 3 | Elem : A | CompareTo A
Index : 4 | Elem : B | CompareTo A
Index : 5 | Elem : B | CompareTo B
Index : 6 | Elem : B | CompareTo B
Index : 7 | Elem : B | CompareTo B
Index : 8 | Elem : C | CompareTo B
Index : 9 | Elem : C | CompareTo C
Index : 10 | Elem : B | CompareTo C
Index : 11 | Elem : B | CompareTo B
使用它,您可以检查每个不等于前一个元素的元素是否发送到您的数组。
很少有答案/评论已经指出了[].filter.call((是如何工作的。
如果要获取字符串而不是数组,只需.join("")
IE添加
var word = "AAAABBBBCCBB";
function uniqueElements(word){
return [].filter.call(word,(
function(elem,index) {
console.log("Index : "+index+" | Elem : " +elem+" | CompareTo "+word[index-1]);
return word[index-1] !== elem;
}
)).join("");
}
uniqueElements(word);
为了更好地理解,我将代码分成带有内联注释的较小部分。
var word = "AAAABBBBCCBB";
var uniqueElements = function(word){
// this is the filter function
// this function will get each element of the string with its index
var filterFunction = function(elem, index) {
// the elements who pass the following condition are kept
// the condition -
// if the character at the previous index (index-1) is not equal to the
// current element, then keep the element
return word[index-1] !== elem;
}
// the below is equivalent to Array.prototype.filter.call(context, filterFunction)
return [].filter.call(word, filterFunction);
}
console.log(uniqueElements(word));
我会通过如下方式利用Array.prototype.reduce()
来做这个 O(n( 时间;
var str = "AAAABBBBCCBB",
uniques = Array.prototype.reduce.call(str, (p,c,i) => i-1 ? p[p.length-1] !== c ? (p.push(c),p)
: p
: [c]);
console.log(uniques);
var word = "AAAABBBBCCBB";
var unique = word.split('').filter(function(item, i, ar) {
return ar.indexOf(item) === i;
}).join('');
- Angular JS Filter-通过3个复选框进行筛选
- call()和apply()实际上是用来欺骗方法处理类似数组的对象的
- 使用filter和map方法将数组中某些元素的第一个字母大写-JavaScript
- JavaScript中的这个call()-方法是如何工作的
- Slack Oauth/Authorize API Call
- 为什么这个array.filter总是不返回任何内容
- 如何在模态实例中使用filter
- 使用“;布尔“;作为JavaScript中.filter()的参数
- 如何对jquery中的未命名函数执行.call()
- Meteor.call()回调未向模板返回值
- orderBy$filter在项目删除(拼接)后阻止ng重复列表更新
- Object.prototype.hasOwnProperty.call() vs Object.prototype.h
- Http响应拆分安全问题的XMLHTTPRequest/Response用例的Filter实现
- 如何将动态构建的字符串作为http头在http.call中与流星一起传递
- AngularJS.Filter in ng中的多个条件重复
- Function.prototype.call和Function.protoype.all只应用一个参数
- JavaScript.call()函数“;这个“;值返回3
- Angular Filter在指令表达式中不起作用
- 谁可以帮助解释这个JavaScript算法[].filter.call()
- js Array.prototype.filter.call() - 有人可以解释我这段代码是如何工作的