2016-04-11 1 views
-3

Я искал способ вернуться в режим массива, когда я нашел этот ответ:Каков синтаксис этого блока кода?

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; 

Я думал, что частота была массивом, с хранения [v], выступающей в качестве индекса. Что именно происходит в этом блоке кода?

+0

[JavaScript | MDN] (https://developer.mozilla.org/en-US/docs/Web/JavaScript) имеет все, что вам нужно, и 'frequency' не является [array] (https://developer.mozilla.org/en -US/docs/Web/JavaScript/Reference/Global_Objects/Array) это [объект] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) – Andreas

+1

* " Мне нужно всестороннее разбиение всего »* - звучит как босс. Нехорошо. –

+0

Частотная переменная - это объект, который в некоторых языках называется ассоциативным массивом. Возможно, это будет ваша смута. Частотный объект используется в качестве гистограммы – paulski

ответ

2

Это работает для вас?

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; 
    } 
} 

Обратите внимание, что код в ваш вопрос совершенно читаемым. Если вы действительно не можете его прочитать, вы не можете «обвинить его в программисте»: вы просто не очень хорошо разбираетесь в коде и должны работать над этим.

«Создание кода читаемый» не означает, что делает его многословным ... это означает «сделать это очевидным на первом прочтении тому, кто знает синтаксис», и я думаю, что код в ваш вопрос соответствует этому должным образом. Мой код очень многословным и мои комментарии должны быть ненужной: они просто объясняю, что следующая строка кода делает

Единственная строка кода, который «может» нужно поясне-:

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, что я и сделал в подробной форме в своем коде.

Другая вещь, которая, кажется, путает ОП (как отмечено в комментариях), использует синтаксис скобок для доступа к свойствам объекта. Это не редкость в динамически исполняемых языках (и я бы утверждал, что, принимая, как прототипы объектов выполняются в javascript, синтаксис скобок имеет больше смысла, чем синтаксис точки, но это просто оппонент).

В Javascript вы можете получить доступ к свойствам объекта с помощью двух разных синтаксисов: object.property эквивалентен object[property]. Основное различие заключается в том, что при использовании синтаксиса скобок вы можете использовать выражение для оценки имени свойства (или использовать другие переменные, как мы здесь делаем). Например, в C# вы можете сделать то же самое, используя dynamic и ExpandoObject.

Обратите внимание, что хотя это может вас смутить, на самом деле это не так важно для вопроса ... вы могли бы также подумать о том, что frequency является массивом, где индекторы являются объектами, а не последовательным числом, и это будет работать то же (в PHP, например, вы можете добиться этого с помощью массивов с ключами или Dictionary в C#, и это очень типичный шаблон в функциональных языках).

+2

+1 для последнего абзаца. Переписывание не представляется необходимым, и исходный код уже давно комментируется IMO. – Paulpro

+1

Я даже не javascript-кодер, и я это прекрасно понял :-) – Jcl

+0

Я получаю, как store [v] - это номер, на который мы смотрим. То, что я не получаю, - это частота [store [v]] - количество раз, которое v появилось. Есть часть этого, которую я не вижу. –

1

frequency не является массивом. Это объект, который представляет собой карту ключей к значениям. В этом случае ключи являются строками из вашего массива store, а значения - это частоты, которые происходят в этих строках.Один из самых простых способов, чтобы увидеть, что происходит бы добавить пару из console.log с:

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. 
    } 
} 

Run, что и смотреть на консоли, чтобы увидеть, что 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; является обобщающим для:

if (frequency[store[v]]) { 
    frequency[store[v]]++; 
} else { 
    frequency[store[v]] = 1; 
} 

Это происходит потому, что || operator в JavaScript возвращает свой левый операнд, если он truthy и его правый операнд в противном случае, так выражение frequency[store[v]] || 0 оценивается как 0, когда frequency[store[v]] равно undefinedundefined является фальшивым), но как только frequency[store[v]] равно 1 или больше, он принимает значение frequency[store[v]].

1

Сначала пройдите через 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', где 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 
+0

Так что частота [store [v]] примерно аналогична более традиционному «object.parameter», с содержимое [] служит тем, что будет после «.»? Или, говоря иначе, «частота [store [v]]» примерно равна «frequency.firstValue», а затем «frequency.secondValue» и т. Д.? –

+0

@SpaceOstrich yes, оператор '[]' является еще одним способом доступа к свойствам объекта js. У вас есть идея правильно. – Kafeaulait

Смежные вопросы