ไม่มีความจำเป็นต้องเปลี่ยนเป็นเป็นMap
Array
คุณสามารถสร้างmap
และfilter
ฟังก์ชั่นสำหรับMap
วัตถุ:
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;
}
ตัวอย่างเช่นคุณสามารถต่อท้ายปัง (เช่น!
ตัวอักษร) กับค่าของแต่ละรายการของแผนที่ที่มีคีย์เป็นแบบดั้งเดิม
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>
คุณสามารถเพิ่มmap
และfilter
วิธีการMap.prototype
เพื่อให้อ่านดีขึ้น แม้ว่าโดยทั่วไปจะไม่ได้รับการแนะนำให้ปรับเปลี่ยนต้นแบบต้นแบบ แต่ฉันเชื่อว่าอาจมีข้อยกเว้นในกรณีของmap
และfilter
สำหรับ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>
แก้ไข:ในคำตอบของ Bergi เขาได้สร้างฟังก์ชั่นทั่วไปmap
และตัวfilter
สร้างสำหรับวัตถุที่ทำซ้ำได้ทั้งหมด ข้อได้เปรียบของการใช้พวกมันคือเพราะมันเป็นฟังก์ชั่นเครื่องกำเนิดไฟฟ้าพวกมันไม่ได้จัดสรรวัตถุที่ทำซ้ำได้ระดับกลาง
ตัวอย่างเช่นฉันmap
และfilter
ฟังก์ชั่นที่กำหนดไว้ข้างต้นสร้างMap
วัตถุใหม่ ดังนั้นการเรียกobject.filter(primitive).map(appendBang)
จะสร้างMap
วัตถุใหม่สองรายการ:
var intermediate = object.filter(primitive);
var result = intermediate.map(appendBang);
การสร้างออบเจกต์แบบ iterable ระดับกลางนั้นมีราคาแพง ฟังก์ชั่นเครื่องกำเนิดของ Bergi แก้ปัญหานี้ได้ พวกเขาไม่ได้จัดสรรวัตถุกลาง แต่อนุญาตให้ตัววนซ้ำหนึ่งตัวป้อนค่าของมันไปอย่างเกียจคร้านต่อไป การเพิ่มประสิทธิภาพแบบนี้เรียกว่าการรวมหรือการตัดไม้ทำลายป่าในภาษาการเขียนโปรแกรมการทำงานและสามารถปรับปรุงประสิทธิภาพของโปรแกรมอย่างมีนัยสำคัญ
ปัญหาเดียวที่ฉันมีกับฟังก์ชั่นเครื่องกำเนิดของ Bergi คือพวกมันไม่เฉพาะเจาะจงกับMap
วัตถุ แต่จะถูกวางสำหรับวัตถุที่ทำซ้ำได้ทั้งหมด ดังนั้นแทนที่จะเรียกฟังก์ชั่นการโทรกลับด้วย(value, key)
คู่ (อย่างที่ฉันคาดหวังเมื่อทำแผนที่เหนือMap
) มันเรียกฟังก์ชั่นการโทรกลับด้วย(value, index)
คู่ ไม่อย่างนั้นมันเป็นทางออกที่ยอดเยี่ยมและฉันขอแนะนำให้ใช้อย่างแน่นอนกับโซลูชั่นที่ฉันให้ไว้
ดังนั้นนี่คือฟังก์ชันตัวสร้างเฉพาะที่ฉันจะใช้สำหรับการจับคู่และกรองMap
วัตถุ:
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;
}
สามารถใช้ดังนี้:
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>
หากคุณต้องการอินเทอร์เฟซที่คล่องแคล่วมากขึ้นคุณสามารถทำสิ่งนี้:
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>
หวังว่าจะช่วย