这个代码块的语法是什么?
What is the syntax of this block of code?
当我找到这个答案时,我正在寻找一种方法来 return 数组的模式:
var store = ['1','2','2','3','4'];
var frequency = {}; // array of frequency.
var max = 0; // holds the max frequency.
var result; // holds the max frequency element.
for(var v in store) {
frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
if(frequency[store[v]] > max) { // is this frequency > max so far ?
max = frequency[store[v]]; // update max.
result = store[v]; // update result.
}
}
这段代码运行完美,我对它的理解非常好,我能够输出最常见的值和该值出现的次数。但是,这个代码块对我来说毫无意义。具体行:
frequency[store[v]]=(frequency[store[v]] || 0)+1;
我还以为frequency是一个数组,以store[v]作为索引。此代码块中到底发生了什么?
这对你有用吗?
for(var v in store) {
numberWeAreLookingAt = store[v];
// we hadn't gone through this number yet, so it's not defined
// as a property in the object "frequency"
if(frequency[numberWeAreLookingAt] === undefined)
frequency[numberWeAreLookingAt] = 0; // let's initialize that property with the
// number zero, in it we will hold the
// number of times it appeared
// Sum 1 to the times it appeared already (or zero if we
// initialized it on the "if" above)
frequency[numberWeAreLookingAt] = frequency[numberWeAreLookingAt] + 1;
// the times this number appeared is more than "max"?
if(frequency[numberWeAreLookingAt] > max) {
// then now "max" is the times this number appeared
max = frequency[numberWeAreLookingAt];
// and the result is this number
result = numberWeAreLookingAt;
}
}
请注意,您问题中的代码完全可读。如果你真的看不懂它,你就不能"blame it on the programmer":你只是不太理解代码,应该努力。
"Making code readable" 并不意味着冗长......它意味着 "make it obvious on a first read to whoever knows the syntax",我认为您问题中的代码非常适合。我的代码非常冗长,不需要我的评论:它们只是解释下一行代码的作用
"may"唯一需要解释的代码行是:
frequency[store[v]]=(frequency[store[v]] || 0)+1;
你可以在上面看到它的分解...x = (x || 0)+1
表示 get x if it's defined, or 0 if it's not: then add 1 and assign back to x
,这是我在代码中以详细形式所做的。
其他似乎混淆 OP(如评论中所述)的事情是使用括号语法访问对象属性。这在动态执行的语言中并不少见(我认为,考虑到对象原型在 javascript 中的完成方式,括号语法比点语法更有意义,但这只是一种观点)。
在 Javascript 中,您可以使用两种不同的语法访问对象属性:object.property
等同于 object[property]
。主要区别在于,当使用括号语法时,您可以使用表达式来计算 属性 名称(或使用其他变量,就像我们在这里所做的那样)。例如,在 C# 中,您可以使用 dynamic
和 ExpandoObject
.
执行相同的操作
请注意,虽然这可能会让您感到困惑,但它对这个问题来说并不是那么重要......您还可以认为 frequency
是一个数组,其中索引器是对象,而不是序列号,并且它的工作方式相同(例如,在 PHP 中,您可以使用键控数组或 C# 中的 Dictionary
来实现此目的,这是函数式语言中非常典型的模式)。
frequency
不是数组。它是一个对象,是键到值的映射。在这种情况下,键是 store
数组中的字符串,值是这些字符串出现的频率。查看正在发生的事情的最简单方法之一是添加几个 console.log
s:
var store = ['1','2','2','3','4'];
var frequency = {}; // array of frequency.
var max = 0; // holds the max frequency.
var result; // holds the max frequency element.
for(var v in store) {
frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
console.log( frequency );
if(frequency[store[v]] > max) { // is this frequency > max so far ?
max = frequency[store[v]]; // update max.
console.log( 'Found new max!', max + ' occurrences of \'' + store[v] + '\'' );
result = store[v]; // update result.
}
}
运行 然后查看控制台以了解 frequency
对象在每次迭代后包含的内容。这就是我得到的 Chrome:
Object {1: 1}
Found new max! 1 occurrences of '1'
Object {1: 1, 2: 1}
Object {1: 1, 2: 2}
Found new max! 2 occurrences of '2'
Object {1: 1, 2: 2, 3: 1}
Object {1: 1, 2: 2, 3: 1, 4: 1}
frequency[store[v]]=(frequency[store[v]] || 0)+1;
是 shorthand 用于:
if (frequency[store[v]]) {
frequency[store[v]]++;
} else {
frequency[store[v]] = 1;
}
这是因为 JavaScript returns 中的 || operator 如果为真,则其左操作数为真,否则为右操作数,因此表达式 frequency[store[v]] || 0
的计算结果为 0
当 frequency[store[v]]
为 undefined
时(因为 undefined
是假的),但是一旦 frequency[store[v]]
为 1
或更大,它的计算结果为 frequency[store[v]]
.
首先,浏览 this tutorial 以了解 Javascript 数组和 Javascript 对象之间的区别。然后你会像这样阅读代码:
var store = ['1','2','2','3','4']; // store[0] == '1', store[1] = '2', etc.
var frequency = {}; // array of frequency. // frequency.'1' = undefined
然后,当分配发生时,它更容易理解。 frequency[store[v]]
只是 frequency.'1'
where v == 0
,这意味着您正在访问对象 frequency
及其由字符串 1
命名的字段。 javascript 对象可以有任何名称的字段,例如frequency.'apple'
、frequency.'table'
等。在您赋予它们价值之前,它们只是未定义的。
那么作业就更容易阅读了
if (frequency.'1' is undefined)
store the value [0 + 1] into frequency.'1'
else increment the value by 1
当我找到这个答案时,我正在寻找一种方法来 return 数组的模式:
var store = ['1','2','2','3','4'];
var frequency = {}; // array of frequency.
var max = 0; // holds the max frequency.
var result; // holds the max frequency element.
for(var v in store) {
frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
if(frequency[store[v]] > max) { // is this frequency > max so far ?
max = frequency[store[v]]; // update max.
result = store[v]; // update result.
}
}
这段代码运行完美,我对它的理解非常好,我能够输出最常见的值和该值出现的次数。但是,这个代码块对我来说毫无意义。具体行:
frequency[store[v]]=(frequency[store[v]] || 0)+1;
我还以为frequency是一个数组,以store[v]作为索引。此代码块中到底发生了什么?
这对你有用吗?
for(var v in store) {
numberWeAreLookingAt = store[v];
// we hadn't gone through this number yet, so it's not defined
// as a property in the object "frequency"
if(frequency[numberWeAreLookingAt] === undefined)
frequency[numberWeAreLookingAt] = 0; // let's initialize that property with the
// number zero, in it we will hold the
// number of times it appeared
// Sum 1 to the times it appeared already (or zero if we
// initialized it on the "if" above)
frequency[numberWeAreLookingAt] = frequency[numberWeAreLookingAt] + 1;
// the times this number appeared is more than "max"?
if(frequency[numberWeAreLookingAt] > max) {
// then now "max" is the times this number appeared
max = frequency[numberWeAreLookingAt];
// and the result is this number
result = numberWeAreLookingAt;
}
}
请注意,您问题中的代码完全可读。如果你真的看不懂它,你就不能"blame it on the programmer":你只是不太理解代码,应该努力。
"Making code readable" 并不意味着冗长......它意味着 "make it obvious on a first read to whoever knows the syntax",我认为您问题中的代码非常适合。我的代码非常冗长,不需要我的评论:它们只是解释下一行代码的作用
"may"唯一需要解释的代码行是:
frequency[store[v]]=(frequency[store[v]] || 0)+1;
你可以在上面看到它的分解...x = (x || 0)+1
表示 get x if it's defined, or 0 if it's not: then add 1 and assign back to x
,这是我在代码中以详细形式所做的。
其他似乎混淆 OP(如评论中所述)的事情是使用括号语法访问对象属性。这在动态执行的语言中并不少见(我认为,考虑到对象原型在 javascript 中的完成方式,括号语法比点语法更有意义,但这只是一种观点)。
在 Javascript 中,您可以使用两种不同的语法访问对象属性:object.property
等同于 object[property]
。主要区别在于,当使用括号语法时,您可以使用表达式来计算 属性 名称(或使用其他变量,就像我们在这里所做的那样)。例如,在 C# 中,您可以使用 dynamic
和 ExpandoObject
.
请注意,虽然这可能会让您感到困惑,但它对这个问题来说并不是那么重要......您还可以认为 frequency
是一个数组,其中索引器是对象,而不是序列号,并且它的工作方式相同(例如,在 PHP 中,您可以使用键控数组或 C# 中的 Dictionary
来实现此目的,这是函数式语言中非常典型的模式)。
frequency
不是数组。它是一个对象,是键到值的映射。在这种情况下,键是 store
数组中的字符串,值是这些字符串出现的频率。查看正在发生的事情的最简单方法之一是添加几个 console.log
s:
var store = ['1','2','2','3','4'];
var frequency = {}; // array of frequency.
var max = 0; // holds the max frequency.
var result; // holds the max frequency element.
for(var v in store) {
frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
console.log( frequency );
if(frequency[store[v]] > max) { // is this frequency > max so far ?
max = frequency[store[v]]; // update max.
console.log( 'Found new max!', max + ' occurrences of \'' + store[v] + '\'' );
result = store[v]; // update result.
}
}
运行 然后查看控制台以了解 frequency
对象在每次迭代后包含的内容。这就是我得到的 Chrome:
Object {1: 1}
Found new max! 1 occurrences of '1'
Object {1: 1, 2: 1}
Object {1: 1, 2: 2}
Found new max! 2 occurrences of '2'
Object {1: 1, 2: 2, 3: 1}
Object {1: 1, 2: 2, 3: 1, 4: 1}
frequency[store[v]]=(frequency[store[v]] || 0)+1;
是 shorthand 用于:
if (frequency[store[v]]) {
frequency[store[v]]++;
} else {
frequency[store[v]] = 1;
}
这是因为 JavaScript returns 中的 || operator 如果为真,则其左操作数为真,否则为右操作数,因此表达式 frequency[store[v]] || 0
的计算结果为 0
当 frequency[store[v]]
为 undefined
时(因为 undefined
是假的),但是一旦 frequency[store[v]]
为 1
或更大,它的计算结果为 frequency[store[v]]
.
首先,浏览 this tutorial 以了解 Javascript 数组和 Javascript 对象之间的区别。然后你会像这样阅读代码:
var store = ['1','2','2','3','4']; // store[0] == '1', store[1] = '2', etc.
var frequency = {}; // array of frequency. // frequency.'1' = undefined
然后,当分配发生时,它更容易理解。 frequency[store[v]]
只是 frequency.'1'
where v == 0
,这意味着您正在访问对象 frequency
及其由字符串 1
命名的字段。 javascript 对象可以有任何名称的字段,例如frequency.'apple'
、frequency.'table'
等。在您赋予它们价值之前,它们只是未定义的。
那么作业就更容易阅读了
if (frequency.'1' is undefined)
store the value [0 + 1] into frequency.'1'
else increment the value by 1