2014-01-24 2 views
2

Есть ли более совершенная идиома для автоинициализации значений карты до 0, чем следующая? В следующем коде есть асимметрия между подходом к , добавляющим значение для цели типа Список по сравнению с int.Идиома для автоинициализации значений карты до 0

main() { 
    addToList(Map m, v) => 
    m..putIfAbsent('foo',() => []).add(v); 

    /////////////////////////////////////////////////////////// 
    // Not allowed (expression is not assignable) 
    // addToScalar(Map m, v) => 
    // m..putIfAbsent('foo',() => 0) += 3; 

    addToScalar1(Map m, v) { 
    m.putIfAbsent('foo',() => 0); 
    m['foo'] += v; 
    return m; 
    } 

    addToScalar2(Map m, v) { 
    if(m.containsKey('foo')) { 
     m['foo'] += v; 
    } else { 
     m['foo'] = v; 
    } 
    return m; 
    } 

    print(addToList({}, 3)); 
    print(addToScalar1({}, 3)); 
    print(addToScalar2({}, 3)); 
} 

Концептуально addToList и addToScalar делать подобные вещи. Но аналог для междунар хранится как значение может быть:

m.putIfAbsent('foo',() => 0) += someValue 

, который не будет работать, так что вернулся из putIfAbsent не может быть назначен. Таким образом, как с помощью рабочих подходов, используемых в скалярном случае, поиск на карте для ключа «foo» выполняется дважды. Можно ли этого избежать с помощью API карт?

+0

Конечно, можно создать подкласс класса карт, который переопределяет добавить() ... – davecom

+0

Да, но версии, которые я видел, все еще просто закрывают внутреннюю карту для делегирования, и вопрос/вопрос остается. Если _addToScalar1_ - это способ сделать это - я в порядке. Но я просто хочу знать, является ли это хорошей идиомой или что-то лучше в api. Также ищите понимание фундаментальной разницы между примерами списка и int. Я думаю, что не было бы проблем, если бы у int был метод под названием _plusEquals_. – user1338952

ответ

3

Нет, вы не можете избежать двух поисков, чтобы изменить значение карты.

Мы рассмотрели, но так и не решили, способ достижения этого (например, метод «обновления»).

Двое кратчайшее/наиболее эффективным решением вашей проблемы являются:

int _returnZero() => 0; // Toplevel or static function. 

... 
    map[key] = map.putIfAbsent(key, _returnZero) + v; 
... 

и:

int value = map[key]; 
map[key] = (value == null) ? v : value + v; 
+1

Есть ли дартбуг, поданный для этой функции? –

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