@@ -1343,7 +1343,8 @@ class _DuplicateItemRecordList {
1343
1343
record._prevDup = null ;
1344
1344
} else {
1345
1345
// adding a duplicate [ItemRecord] to the list
1346
- assert (record.item == _head.item);
1346
+ assert (record.item == _head.item ||
1347
+ record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
1347
1348
if (insertBefore == null ) {
1348
1349
_tail._nextDup = record;
1349
1350
record._prevDup = _tail;
@@ -1369,9 +1370,12 @@ class _DuplicateItemRecordList {
1369
1370
ItemRecord get (item, int afterIndex) {
1370
1371
ItemRecord record;
1371
1372
for (record = _head; record != null ; record = record._nextDup) {
1372
- if ((afterIndex == null || afterIndex < record.currentIndex) &&
1373
- identical (record.item, item)) {
1374
- return record;
1373
+ if (afterIndex == null || afterIndex < record.currentIndex) {
1374
+ if (identical (record.item, item) ||
1375
+ record.item is String && item is String && record.item == item ||
1376
+ record.item is num && record.item.isNaN && item is num && item.isNan) {
1377
+ return record;
1378
+ }
1375
1379
}
1376
1380
}
1377
1381
return null ;
@@ -1414,10 +1418,12 @@ class _DuplicateItemRecordList {
1414
1418
* The list of duplicates is implemented by [_DuplicateItemRecordList] .
1415
1419
*/
1416
1420
class DuplicateMap {
1421
+ static final nanKey = const Object ();
1417
1422
final map = new HashMap <dynamic , _DuplicateItemRecordList >();
1418
1423
1419
1424
void put (ItemRecord record, [ItemRecord insertBefore = null ]) {
1420
- map.putIfAbsent (record.item, () => new _DuplicateItemRecordList ()).add (record, insertBefore);
1425
+ var key = _getKey (record.item);
1426
+ map.putIfAbsent (key, () => new _DuplicateItemRecordList ()).add (record, insertBefore);
1421
1427
}
1422
1428
1423
1429
/**
@@ -1427,9 +1433,10 @@ class DuplicateMap {
1427
1433
* Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
1428
1434
* have any more `a` s needs to return the last `a` not the first or second.
1429
1435
*/
1430
- ItemRecord get (key, [int afterIndex]) {
1436
+ ItemRecord get (value, [int afterIndex]) {
1437
+ var key = _getKey (value);
1431
1438
_DuplicateItemRecordList recordList = map[key];
1432
- return recordList == null ? null : recordList.get (key , afterIndex);
1439
+ return recordList == null ? null : recordList.get (value , afterIndex);
1433
1440
}
1434
1441
1435
1442
/**
@@ -1438,10 +1445,11 @@ class DuplicateMap {
1438
1445
* The list of duplicates also is removed from the map if it gets empty.
1439
1446
*/
1440
1447
ItemRecord remove (ItemRecord record) {
1441
- assert (map.containsKey (record.item));
1442
- _DuplicateItemRecordList recordList = map[record.item];
1448
+ var key = _getKey (record.item);
1449
+ assert (map.containsKey (key));
1450
+ _DuplicateItemRecordList recordList = map[key];
1443
1451
// Remove the list of duplicates when it gets empty
1444
- if (recordList.remove (record)) map.remove (record.item );
1452
+ if (recordList.remove (record)) map.remove (key );
1445
1453
return record;
1446
1454
}
1447
1455
@@ -1451,5 +1459,8 @@ class DuplicateMap {
1451
1459
map.clear ();
1452
1460
}
1453
1461
1462
+ /// Required to handle num.NAN as a Map value
1463
+ dynamic _getKey (value) => value is num && value.isNaN ? nanKey : value;
1464
+
1454
1465
String toString () => "DuplicateMap($map )" ;
1455
1466
}
0 commit comments