I am new to JavaScript and Python, and programming in general.
I want to store data about common English phonograms in a JavaScript data object. There are about 80 phonograms. Each phonogram has one or more possible pronunciations. Each phonogram’s pronunciation would have a list of one or more word examples (say, 30 maximum) which would include the IPA phonetic symbols and a translation to a foreign language. E.g., the phonogram ‘ea’ has three pronunciation,
(1) 'iːˈ, (2)ˈɛˈ & (3)ˈeɪˈ:
(1)ˈbeadˈ, 'feat', 'beat'...
(2)'bread', 'head', 'dead'...
(3)'break'...
Is there a built-in data structure best suited for this? I am thinking of a class to make these objects and store it in an array or something. And how should I write my text for populating the the data objects?
JavaScript has four fundamental structured data types:
objects, which have properties, which have keys (names which are strings or Symbols) and values (any type)
arrays, which have elements, which have indexes and values (arrays are technically objects, but ignore that for now)
Map, which has entries, which have keys (any type) and values (any type)
Set, which has unique entries of any type (probably not useful for what you're doing)
It sounds like you'd probably want either an object or a Map where the keys are the phonographs and the values are objects. Within each object, you'd probably have another Map or object keyed by the pronunciation where the values are objects giving further information (examples and translations).
Here's an example using Maps, which you initialize by passing an array of arrays into the Map constructor:
const data = new Map([
[
"ea",
{
pronunciations: new Map([
[
"iː",
{
examples: ["bead", "feat"],
transations: [/*...*/]
}
]
]),
otherInfo: /*...*/
}
],
// ...the other 79 entries...
]);
Getting the data for an entry based on the phonogram:
const entry = data.get("ea");
The entry object will have a pronunciations property with a Map of the pronunciations and the objects (with examples and translations) they map to.
More on MDN:
Map
Object
Array
map of an array should do the work.
map key can contain an identifier while the map value is an array that can contain the pronunciation.
map is a (key, value) pair where value will be an array/[] in your case.
Related
I have an array like this(data retrieved from mySql and json_encode() in PHP, coming back as a json object(totally 19 elements in this array, and all the objects in different order in the element)):
const array=[
[{"name":"jason"},{"age":16},{"location":"London"}],
[{"age":24},{"location":"Tokyo"},{"name":"amy"}]
]
How to convert it to an array like this, removing curly brackets?
const array=[
{"name":"jason","age":16,"location":"London"},
{"name":"amy","age":24,"location":"Tokyo"}
]
I have tried to convert to string, then
String.replace(/[{}]/g, '');
But what's next? I got stuck at converting back to array again.
And the other question is:For an array like this, when to access the keys and values, is it neccesary to re-structure the keys and values to make them the same order in each element, otherwise it doesn't look nice and is not easy to access?
[
[{"name":"jason"},{"age":16},{"location":"London"}],
[{"age":24},{"location":"Tokyo"},{"name":"amy"}]
]
Any tips on how to think about flattening this will be much appreciated!
The .replace() method is used for strings, not objects/arrays. Instead, you can merge the objects within each inner array together by using .map() to trasform each array, and Object.assign() to merge the given array of objects.
See example below:
const array = [
[{"name":"jason"},{"age":16},{"location":"London"}],
[{"age":24},{"location":"Tokyo"},{"name":"amy"}]
];
const res = array.map(inner => Object.assign({}, ...inner));
console.log(res);
The order of your (string) keys in the resulting objects will appear in the order that they're inserted, so as your object order is different for each inner array, your resulting object's key-ordering will also be different once they're merged. However, this shouldn't matter too much as relying on object key ordering is often not the best idea, and can be done more reliably using other methods.
I am trying to apply some examples to better understand the difference of Map and Set and the behaviour of each one seems confusing. Look at the examples and output below
Map example:
let nameMap = new Map([
['name', 'stack'],
['name', 'overflow'],
['domain', 'technology']
]);
// iterate over keys (nameMap)
for (let name of nameMap) {
console.log(JSON.stringify(name));
}
output:
["name","overflow"]
["domain","technology"]
Set Example:
let nameSet = new Set([
['name', 'stack'],
['name', 'overflow'],
['domain', 'technology']
]);
// iterate over keys (nameSet)
for (let name of nameSet) {
console.log(JSON.stringify(name));
}
output:
["name","stack"]
["name","overflow"]
["domain","technology"]
My question is why map returns only the second occurence of two similar objects?
Set returns all three objects even though first two keys and values being same, while it supposed to delete one of them.
My question is why map returns only the second occurence of two similar objects?
Because a Map contains a set of key-value pairs. You can only have one value per key. In the constructor, each array is represents [key, value]). The second bit of data with the key 'name' overwrites the first one.
Set returns all three objects even though first two keys and values being same, while it supposed to delete one of them.
A set stores a set of unique values. Each array (like ['name', 'stack']) is one value.
Because Sets are like arrays - they just store the values in a list. Therefore, the constructor will add all three arrays to the new Set as values. The Map constructor is similar to Object.fromEntries - the first item in each sub-array is the key, the second the value. You can't store keys in a Set, only values - so the two items have to be exactly the same, and a primitive, to be excluded from the Set.
A Map is a container for key-value pairs. In your input, name and domain will become keys. Since a key can only exist once, the key name gets deduplicated.
A Set is an array of values which deduplicates the values themselves. Since there aren't any identical values in your input, all are retained.
I have an array of uniform objects:
var objects = [{
id: 1,
name: "one"
}, {
id: 2,
name: "two"
}];
And I'm converting these to a Map by using the id property of each object as Map keys:
var map = new Map();
objects.forEach(obj => map.set(obj.id, obj));
However, I'd like to do the conversion without:
having to manually create a new map object myself, and
having to manually iterate over the array and calling set myself
Additionally, I don't feel I should be making a utility function for this presumably native functionality.
Note: search queries for js array to map, or js convert array to map, or js map from array are all bloated with stone-age-era answers with Object, or solutions with a utility function. I'm looking for the native approach here.
I.e. I'm looking for the native JavaScript equivalent of mapping an array to a dictionary in C#, for example.
var map = list.ToDictionary(item => item.id);
This is so straightforward and convenient, yet interestingly enough, there is no Map.from in JavaScript (even though there is an Array.from).
I did my research while writing up the question, and I feel I should leave the solution here, as its possible practical applications are many.
I'm looking for the native JavaScript equivalent of mapping an array to a dictionary in C#
Considering a Map can be constructed with an iterable of 2-element arrays, where the first element of each inner array is used as the key, and the second element is used as a value, I believe this is the native JS equivalent, also the shortest:
new Map(objects.map(obj => [obj.id, obj]));
Live demo
This question already has answers here:
Map vs Object in JavaScript
(15 answers)
Maps vs Objects in ES6, When to use?
(6 answers)
Closed 1 year ago.
When to use Map over {}. Everything that could be done with Map could also be achieved using {} i.e. Object except one thing which is setting key of type other than string.
var mp = new Map();
mp.set(1, 'one');
mp.set(2, 'two');
var ob = {};
ob[1] = 'one';
ob[2] = 'two';
console.log(mp);
console.log(mp.get(1));
console.log(typeof mp.keys().next().value);
console.log(ob);
console.log(ob[1]);
console.log(typeof Object.keys(ob)[0]);
Output :
Map { 1 => 'one', 2 => 'two' }
one
number
{ '1': 'one', '2': 'two' }
one
string
Which method should be used at what scenarios when I can do the some thing with any of them.
mozilla documentation is enough descriptive, I believe.
The Map object is a simple key/value map. Any value (both objects and primitive values) may be used as either a key or a value.
Objects and maps compared
Objects are similar to Maps in that both let you set keys to values,
retrieve those values, delete keys, and detect whether something is
stored at a key. Because of this (and because there were no built-in
alternatives), Objects have been used as Maps historically; however,
there are important differences between Objects and Maps that make
using a Map better:
An Object has a prototype, so there are default keys in the map. This
could be bypassed by using map = Object.create(null) since ES5, but was seldom done.
The keys of an Object are Strings and Symbols, whereas they can be any value for a Map, including functions, objects, and or any primitive.
You can get the size of a Map easily with the size property, while the size of an Object must be determined manually.
This does not mean you should use Maps everywhere, objects still are
used in most cases. Map instances are only useful for collections, and
you should consider adapting your code where you have previously used
objects for such. Objects shall be used as records, with fields and
methods. If you're still not sure which one to use, ask yourself the
following questions:
Are keys usually unknown until run time, do you need to look them up dynamically?
Do all values have the same type, and can be used interchangeably?
Do you need keys that aren't strings?
Are key-value pairs often added or removed?
Do you have an arbitrary (easily changing) amount of key-value pairs?
Is the collection iterated?
Those all are signs that you want a Map for a collection. If in
contrast you have a fixed amount of keys, operate on them
individually, and distinguish between their usage, then you want an
object.
Here is a bug I once had:
var scrabbled = {
The: 6,
word: 8,
length: 10,
is: 2,
weird: 9
};
$.each(scrabbled, function(k, v) {
console.log(k, v);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
(jQuery fixed it in 1.9, but it was not a fun day at work till I finally realised what was wrong.)
Yes, I suppose if you restrict yourself to string indices, there's nothing you can do with Map that you can't do with objects; but there's easy things to mess up with objects if you are not careful and doing things in a safe way (like iterating with for...in... without .hasOwnProperty check).
From the MDN,
An Object has a prototype, so there are default keys in the map. This
could be bypassed by using map = Object.create(null) since ES5, but
was seldom done.
The keys of an Object are Strings and Symbols,
whereas they can be any value for a Map, including functions, objects,
and or any primitive.
You can get the size of a Map easily with the
size property, while the size of an Object must be determined
manually.
Maps are usually useful for a collection where your keys are not string and key-value pairs are often removed or added. If your keys are fixed than an object will be better suited.
The difference is Object have strings as key, whereas Map can have any type of key.
If you have a number, and a number as string, then with objects, the key is the same (both get if they are not strings converted to strings), but with maps, the two keys are different and points to different values.
var m = new Map;
m.set(1, 'number 1');
m.set('1', 'string 1');
console.log(m.get(1)); // 'number 1'
console.log(m.get('1')); // 'string 1'
var o = Object.create(null); // an empty object without prototypes
o[1] = 'number 1';
o['1'] = 'string 1';
console.log(o[1]); // 'string 1'
The main reason to use an object over a map is, object works on every systems and maps only with on newr browsers, at least where ES6 is working.
JavaScript Map and Set objects are both iterable objects. Both store object by [key, value] pair.
When to use which? What is the difference between them?
Provided you are talking about the ES6 types, they aren't the same data structure even though the Set might be implemented with a Map.
Your definition of Map is right, but a Set is a collection of unique values, unlike an array which can have duplicates.
var array = [1, 2, 3, 3];
var set = new Set(array); // Will have [1, 2, 3]
assert(set.size, 3);
var map = new Map();
map.set('a', 1);
map.set('b', 2);
map.set('c', 3);
map.set('C', 3);
map.set('a', 4); // Has: a, 4; b, 2; c: 3, C: 3
assert(map.size, 4);
Summary:
Use a Set when your dataset needs to be composed of unique values
Use a Map when you have pairs of associated data. You map the keys to the values
Example Set:
There is a meeting with people coming from different organizations. Some people come from the same organization. We need to compose a list all the different organzations. For this we can use a set since we only want to include every organization once:
const organization = new Set();
organization.add('org1');
organization.add('org2');
organization.add('org3');
organization.add('org1');
organization.add('org3');
organization.add('org1');
for(let org of organization){
console.log(org);
}
Example Map:
We have a pack of dogs and want to assign an age to each dog. We want to map the unique name of each dog to the age of the dog:
const dogs = new Map([['fluffy', 10], ['barkie', 13]]);
dogs.forEach((value, key) => console.log(key, value));
How is Map different from an Object?
An Object is also a collection of key value pairs and can fulfill often the same purpose as a Map can (which is creating key-value pairs). However, there are some key differences between a Map and an Object:
Map is built in Iterable, this allows it to use the for of loop or its implementation of the forEach() method which an plain JS Object cannot use.
Map has some nice built in methods on its prototype which makes working with it very nicely. Because al Objects inherit from Object.prototype is has access to more useful methods. For example, the size() method on Map returns the number of keys in the Map.
var obj = {};
obj.name= "Anand Deep Singh";
console.log(obj.name); //logs "Anand Deep Singh"
similarly in ES6, we can use regular object.
var map = new Map();
map.set("name","Anand Deep Singh");
console.log(map.get("name")); //logs "Anand Deep Singh"
But noticeable thing is a Map isn’t created with the literal object syntax, and that one uses set and get methods to store and access data.
It has a has method to check whether the key exists in the object or not, delete method to delete the object and clear method to clear the entire object.
Set is a unique list of values. It’s simply a unique list.
var set = new Set(["a", "a","e", "b", "c", "b", "b", "b", "d"]);
console.log(set); //logs Set {"a", "e", "b", "c", "d"}
A Set can’t be accessed like an array, and it provides the same methods as a Map.
There are two main data structures:
Objects:
are used for storing keyed collections.
Arrays:
are used for storing ordered collections.
But that’s not enough for real life. That’s why Map and Set also exist.
Map:
is a collection of keyed data items, just like an Object. But the main difference is that Map allows keys of any type.
For instance:
let map = new Map();
map.set('1', 'str1'); // a string key
map.set(1, 'num1'); // a numeric key
map.set(true, 'bool1'); // a boolean key
let hamid = { name: "Hamid" };
// hamid is the key for the map
map.set(hamid, 123); // an object key
Set
: is a special type collection – “set of values” (without keys), where each value may occur only once.
instance:
let set = new Set();
let hamid= { name: "Hamid" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };
// visits, some users come multiple times
set.add(hamid);
set.add(pete);
set.add(mary);
set.add(hamid);
set.add(mary);
// set keeps only unique values
alert( set.size ); // 3
https://javascript.info/map-set
In Map(), keys can be of any type [String, number, object] except for
regular objects that must be strings.
The Set is a one-dimensional array with unique keys, while the Map is
a two-dimensional array with key-value pairs, where each key shall be
unique.
For Map(), we allow the use of other primitive types (including NaN). As a result, developers are able to link to other types of data.
A Set consists of a collection of unique values, while a Map is a pair of associated data when we map the keys to the values. Both Map and Set have similar methods, such as .has(), .get(), .delete(), and .size().
The difference is that a map has a key-value pair and two dimensions. It is possible to convert both 2D arrays and arrays to sets.
To summarise, Map is used for key-value pair collections, while Set is used for unique value collections.
if you have unique values that you want to put in the set, then you should use Set as it is made for unique values
else if you don't have any issues with 2 or more same values then you should prefer Map