Không cần phải chuyển đổi Map
thành một Array
. Bạn chỉ có thể tạo map
và các filter
chức năng cho Map
các đối tượng:
function map(functor, object, self) {
var result = new Map;
object.forEach(function (value, key, object) {
result.set(key, functor.call(this, value, key, object));
}, self);
return result;
}
function filter(predicate, object, self) {
var result = new Map;
object.forEach(function (value, key, object) {
if (predicate.call(this, value, key, object)) result.set(key, value);
}, self);
return result;
}
Ví dụ: bạn có thể nối một tiếng nổ (tức là !
ký tự) vào giá trị của mỗi mục trên bản đồ có khóa là nguyên thủy.
var object = new Map;
object.set("", "empty string");
object.set(0, "number zero");
object.set(object, "itself");
var result = map(appendBang, filter(primitive, object));
alert(result.get("")); // empty string!
alert(result.get(0)); // number zero!
alert(result.get(object)); // undefined
function primitive(value, key) {
return isPrimitive(key);
}
function appendBang(value) {
return value + "!";
}
function isPrimitive(value) {
var type = typeof value;
return value === null ||
type !== "object" &&
type !== "function";
}
<script>
function map(functor, object, self) {
var result = new Map;
object.forEach(function (value, key, object) {
result.set(key, functor.call(this, value, key, object));
}, self || null);
return result;
}
function filter(predicate, object, self) {
var result = new Map;
object.forEach(function (value, key, object) {
if (predicate.call(this, value, key, object)) result.set(key, value);
}, self || null);
return result;
}
</script>
Bạn cũng có thể thêm map
và filter
các phương thức Map.prototype
để làm cho nó đọc tốt hơn. Mặc dù nói chung không nên sửa đổi các nguyên mẫu gốc nhưng tôi tin rằng một ngoại lệ có thể được tạo ra trong trường hợp map
và filter
cho Map.prototype
:
var object = new Map;
object.set("", "empty string");
object.set(0, "number zero");
object.set(object, "itself");
var result = object.filter(primitive).map(appendBang);
alert(result.get("")); // empty string!
alert(result.get(0)); // number zero!
alert(result.get(object)); // undefined
function primitive(value, key) {
return isPrimitive(key);
}
function appendBang(value) {
return value + "!";
}
function isPrimitive(value) {
var type = typeof value;
return value === null ||
type !== "object" &&
type !== "function";
}
<script>
Map.prototype.map = function (functor, self) {
var result = new Map;
this.forEach(function (value, key, object) {
result.set(key, functor.call(this, value, key, object));
}, self || null);
return result;
};
Map.prototype.filter = function (predicate, self) {
var result = new Map;
this.forEach(function (value, key, object) {
if (predicate.call(this, value, key, object)) result.set(key, value);
}, self || null);
return result;
};
</script>
Chỉnh sửa: Trong câu trả lời của Bergi, ông đã tạo ra các hàm chung map
và trình filter
tạo cho tất cả các đối tượng lặp lại. Ưu điểm của việc sử dụng chúng là vì chúng là các hàm tạo, chúng không phân bổ các đối tượng lặp trung gian.
Ví dụ, hàm của tôi map
và các filter
hàm được định nghĩa ở trên tạo các Map
đối tượng mới . Do đó, việc gọi object.filter(primitive).map(appendBang)
sẽ tạo ra hai Map
đối tượng mới :
var intermediate = object.filter(primitive);
var result = intermediate.map(appendBang);
Tạo các đối tượng lặp trung gian là tốn kém. Các chức năng tạo của Bergi giải quyết vấn đề này. Họ không phân bổ các đối tượng trung gian nhưng cho phép một trình vòng lặp đưa các giá trị của nó một cách lười biếng sang kế tiếp. Loại tối ưu hóa này được gọi là hợp nhất hoặc phá rừng trong các ngôn ngữ lập trình chức năng và nó có thể cải thiện đáng kể hiệu suất chương trình.
Vấn đề duy nhất tôi gặp phải với các hàm tạo của Bergi là chúng không dành riêng cho Map
các đối tượng. Thay vào đó, chúng được khái quát cho tất cả các đối tượng lặp lại. Do đó, thay vì gọi các hàm gọi lại bằng (value, key)
các cặp (như tôi mong đợi khi ánh xạ qua a Map
), nó gọi các hàm gọi lại bằng (value, index)
các cặp. Mặt khác, đó là một giải pháp tuyệt vời và tôi chắc chắn sẽ khuyên bạn nên sử dụng nó trên các giải pháp mà tôi đã cung cấp.
Vì vậy, đây là các hàm tạo cụ thể mà tôi sẽ sử dụng để ánh xạ và lọc Map
các đối tượng:
function * map(functor, entries, self) {
var that = self || null;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
yield [key, functor.call(that, value, key, entries)];
}
}
function * filter(predicate, entries, self) {
var that = self || null;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
if (predicate.call(that, value, key, entries)) yield [key, value];
}
}
function toMap(entries) {
var result = new Map;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
result.set(key, value);
}
return result;
}
function toArray(entries) {
var array = [];
for (var entry of entries) {
array.push(entry[1]);
}
return array;
}
Chúng có thể được sử dụng như sau:
var object = new Map;
object.set("", "empty string");
object.set(0, "number zero");
object.set(object, "itself");
var result = toMap(map(appendBang, filter(primitive, object.entries())));
alert(result.get("")); // empty string!
alert(result.get(0)); // number zero!
alert(result.get(object)); // undefined
var array = toArray(map(appendBang, filter(primitive, object.entries())));
alert(JSON.stringify(array, null, 4));
function primitive(value, key) {
return isPrimitive(key);
}
function appendBang(value) {
return value + "!";
}
function isPrimitive(value) {
var type = typeof value;
return value === null ||
type !== "object" &&
type !== "function";
}
<script>
function * map(functor, entries, self) {
var that = self || null;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
yield [key, functor.call(that, value, key, entries)];
}
}
function * filter(predicate, entries, self) {
var that = self || null;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
if (predicate.call(that, value, key, entries)) yield [key, value];
}
}
function toMap(entries) {
var result = new Map;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
result.set(key, value);
}
return result;
}
function toArray(entries) {
var array = [];
for (var entry of entries) {
array.push(entry[1]);
}
return array;
}
</script>
Nếu bạn muốn một giao diện trôi chảy hơn thì bạn có thể làm một cái gì đó như thế này:
var object = new Map;
object.set("", "empty string");
object.set(0, "number zero");
object.set(object, "itself");
var result = new MapEntries(object).filter(primitive).map(appendBang).toMap();
alert(result.get("")); // empty string!
alert(result.get(0)); // number zero!
alert(result.get(object)); // undefined
var array = new MapEntries(object).filter(primitive).map(appendBang).toArray();
alert(JSON.stringify(array, null, 4));
function primitive(value, key) {
return isPrimitive(key);
}
function appendBang(value) {
return value + "!";
}
function isPrimitive(value) {
var type = typeof value;
return value === null ||
type !== "object" &&
type !== "function";
}
<script>
MapEntries.prototype = {
constructor: MapEntries,
map: function (functor, self) {
return new MapEntries(map(functor, this.entries, self), true);
},
filter: function (predicate, self) {
return new MapEntries(filter(predicate, this.entries, self), true);
},
toMap: function () {
return toMap(this.entries);
},
toArray: function () {
return toArray(this.entries);
}
};
function MapEntries(map, entries) {
this.entries = entries ? map : map.entries();
}
function * map(functor, entries, self) {
var that = self || null;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
yield [key, functor.call(that, value, key, entries)];
}
}
function * filter(predicate, entries, self) {
var that = self || null;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
if (predicate.call(that, value, key, entries)) yield [key, value];
}
}
function toMap(entries) {
var result = new Map;
for (var entry of entries) {
var key = entry[0];
var value = entry[1];
result.set(key, value);
}
return result;
}
function toArray(entries) {
var array = [];
for (var entry of entries) {
array.push(entry[1]);
}
return array;
}
</script>
Mong rằng sẽ giúp.