I am trying to use higher-order functions to fills a 3x3 2d array. To be specific, i need to use array.map function to finish this. so far my code is:
function Matrix(m,n){
var mat = Array.apply(null, new Array(m)).map(
Array.prototype.valueOf,
new Array(n)
);
return mat;
}
restaurants = Matrix(3,3);
restaurants.map(
function(row,i){
return row.map(function(cell,j){
return new BorderedCell(ToString(ancestry[i][j]));
});
});
There is no output when I try to display restaurants. it seems like the code stoped at
function(row,i){}
and won't go further.
How can I fix this? Any help will be appreciated.
Edit: I am trying to fill A 2D array with object BorderedCell. My problem is I don't know how to use double mapping to go through the whole matrix, which I supposed to do.
If expected result of restaurants is [[0,1,2],[0,1,2],[0,1,2]] you can use Array.from(), Array.prototype.keys()
function arr(len) {
return Array.from(Array(len).keys())
}
function Matrix(m, n) {
return arr(m).map(arr.bind(null, n));
}
var restaurants = Matrix(3, 3);
console.log(restaurants);
Related
I have the map function.
function test2() {
let data = [
["a","aa","aaa"],
["b","bb","bbb"],
["x","xx","xxx"],
["c","cc","ccc"]
];
data.map(function(row){
row[1]=row[1]+" ZZZ"
row[2]=row[2]+" AAA"
return data
})
console.log(data)
}
I am unclear on the best way to return a map function
both these work
return data
and
return row
In my reading on map I think this is the correct way
return row
What is the best way to return a map function?
This is a misuse of map, so it doesn't matter here because you're ignoring the return value from map. If you inspect that, you'll see what the difference is.
let result = data.map(function(row){ return data });
console.log(result);
result = data.map(function(row){ return row });
console.log(result);
What you really want though is forEach:
data.forEach(function(row){
row[1]=row[1]+" ZZZ"
row[2]=row[2]+" AAA"
});
Or a normal for loop.
map's purpose is to take an array and produce a new array as the result of running a function on each element. You only want to iterate to carry out side effects though.
This question would seem basic but I'm stuck on this. I've got a class which is not a component, I used it to initialize a DB and do DB CRUD operations. The class has a method readMatrix which reads a dictionnary from a DB and returns it as a matrix. I can check the value of the matrix in the console and it is correct. However the value which is returned to the calling function is "undefined" instead of what I'm seeing in the console log. I tried to fix it with Redux/Hooks and found this way too complexe for a novice like me (I'm using functions/hooks as components, but a class for DB management).
Here's the code of the class:
readMatrix (r,c,id) {
const row = new Array(c).fill(null);
var tempMatrix=[];
for (let i=0; i<r; i++){
tempMatrix.push([...row])
}
var restaurantRef = app.database().ref("/restaurants");
restaurantRef.orderByKey().equalTo("1").on("child_added", function(snapshot){
// console.log(snapshot.child("/layout").val());
var restaurant=snapshot.child("/layout").val();
for (const [key, value] of Object.entries(restaurant)) {
let i=key;
for (const [rowkey, rowvalue] of Object.entries(value)){
let j=rowkey;
tempMatrix[i][j]=rowvalue;
}
}
console.log(tempMatrix);
return(tempMatrix);
});
}
And here's the calling function:
useEffect(()=>{
setMatrix(FirebaseClass.readMatrix(matrixHeight,matrixWidth, 1))
console.log(matrix);
}, []);
Any idea on what's wrong there ?
Thanks for the answer(s)
Here's the only think that fixed it.
Declare readMatrix as async.
Get the value in the matrix the following way:
FirebaseClass.readMatrix(matrixHeight,matrixWidth, 1).then(setMatrix)
Hope the answer is clearer than the question.
Currently, I have a huge JavaScript array where each element is like this:
[{"open":235.86,
"high":247.13,
"low":231.5,
"close":244.1,
"volume":55025735,
"date":"2019-05-01T21:00:00.000Z"}
...
I need to remove everything except the price after high. What is the most efficient way I can do this?
I've tried popping the individual elements, but I can't help but feel as if there is a more efficient/easier way to do this.
So hopefully the ending array would just be [235.86].
The below code should work. It's efficient enough :D
for (i in arrayName){
// Loops through array
delete arrayName[i].high
delete arrayName[i].low
delete arrayName[i].close
delete arrayName[i].volume
delete arrayName[i].date
// Deletes unwanted properties
}
console.log(arrayName)
// Print output
One potential solution would be to map the array to a new array like so:
const yourArray = [
{"open":235.86, "high":247.13, "low":231.5, "close":244.1, "volume":55025735},
{"open":257.52, "high":234.53, "low":220.2, "close":274.1, "volume":23534060},
]
const mappedArray = yourArray.map(el => el.open);
// mappedArray = [235.86, 257.52]
Check out the MDN documentation for the map method, Array.prototype.map()
Note: The above example uses ECMAScript 6 arrow functions and implicit returns. It is functionally equivalent to:
const yourArray = [
{"open":235.86, "high":247.13, "low":231.5, "close":244.1, "volume":55025735},
{"open":257.52, "high":234.53, "low":220.2, "close":274.1, "volume":23534060},
]
const mappedArray = yourArray.map(function(el){
return el.open
});
You can use reduce for this scenario. Example
var temp = [{"open":235.86, "high":247.13, "low":231.5, "close":244.1, "volume":55025735, "date":"2019-05-01T21:00:00.000Z"}];
var highValArray = temp.reduce((arr, t) => {
return arr.concat(t['high']);
}, []);
You can learn more about reduce function at the MDN website.
This should work:
your_array.map((item) => {
return item.high
})
PS: I have already searched the forums and have seen the relevant posts for this wherein the same post exists but I am not able to resolve my issue with those solutions.
I have 2 json objects
var json1 = [{uid:"111", addrs:"abc", tab:"tab1"},{uid:"222", addrs:"def", tab:"tab2"}];
var json2 = [{id:"tab1"},{id:"new"}];
I want to compare both these and check if the id element in json2 is present in json1 by comparing to its tab key. If not then set some boolean to false. ie by comparing id:"tab1" in json2 to tab:"tab1 in json1 .
I tried using below solutions as suggested by various posts:
var o1 = json1;
var o2 = json2;
var set= false;
for (var p in o1) {
if (o1.hasOwnProperty(p)) {
if (o1[p].tab!== o2[p].id) {
set= true;
}
}
}
for (var p in o2) {
if (o2.hasOwnProperty(p)) {
if (o1[p].tab!== o2[p].id) {
set= true;
}
}
}
Also tried with underscore as:
_.each(json1, function(one) {
_.each(json2, function(two) {
if (one.tab!== two.id) {
set= true;
}
});
});
Both of them fail for some test case or other.
Can anyone tell any other better method or outline the issues above.
Don't call them JSON because they are JavaScript arrays. Read What is JSON.
To solve the problem, you may loop over second array and then in the iteration check if none of the objects in the first array matched the criteria. If so, set the result to true.
const obj1 = [{uid:"111", addrs:"abc", tab:"tab1"},{uid:"222",addrs:"def", tab:"tab2"}];
const obj2 = [{id:"tab1"},{id:"new"}];
let result = false;
for (let {id} of obj2) {
if (!obj1.some(i => i.tab === id)) {
result = true;
break;
}
}
console.log(result);
Unfortunately, searching the forums and reading the relevant posts is not going to replace THINKING. Step away from your computer, and write down, on a piece of paper, exactly what the problem is and how you plan to solve it. For example:
Calculate for each object in an array whether some object in another array has a tab property whose value is the same as the first object's id property.
There are many ways to do this. The first way involves using array functions like map (corresponding to the "calculate for each" in the question, and some (corresponding to the "some" in the question). To make it easier, and try to avoid confusing ourselves, we'll do it step by step.
function calculateMatch(obj2) {
return obj2.map(doesSomeElementInObj1Match);
}
That's it. Your program is finished. You don't even need to test it, because it's obviously right.
But wait. How are you supposed to know about these array functions like map and some? By reading the documentation. No one help you with that. You have to do it yourself. You have to do it in advance as part of your learning process. You can't do it at the moment you need it, because you won't know what you don't know!
If it's easier for you to understand, and you're just getting started with functions, you may want to write this as
obj2.map(obj1Element => doesSomeElementInObj1Match(obj1Element))
or, if you're still not up to speed on arrow functions, then
obj2.map(function(obj1Element) { return doesSomeElementInObj1Match(obj1Element); })
The only thing left to do is to write doesSomeElementInObj2Match. For testing purposes, we can make one that always returns true:
function doesSomeElementInObj2Match() { return true; }
But eventually we will have to write it. Remember the part of our English description of the problem that's relevant here:
some object in another array has a tab property whose value is the same as the first object's id property.
When working with JS arrays, for "some" we have the some function. So, following the same top-down approach, we are going to write (assuming we know what the ID is):
In the same way as above, we can write this as
function doesSomeElementInObj2Match(id) {
obj2.some(obj2Element => tabFieldMatches(obj2Element, id))
}
or
obj2.some(function(obj2Element) { return tabFieldMatches(obj2Element, id); })
Here, tabFieldMatches is nothing more than checking to make sure obj2Element.tab and id are identical.
We're almost done! but we still have to write hasMatchingTabField. That's quite easy, it turns out:
function hasMatchingTabField(e2, id) { return e2.tab === id; }
In the following, to save space, we will write e1 for obj1Element and e2 for obj2Element, and stick with the arrow functions. This completes our first solution. We have
const tabFieldMatches = (tab, id) { return tab === id; }
const hasMatchingTabField = (obj, id) => obj.some(e => tabFieldMatches(e.tab, id);
const findMatches = obj => obj.some(e => hasMatchingTabField(e1, obj.id));
And we call this using findMatches(obj1).
Old-fashioned array
But perhaps all these maps and somes are a little too much for you at this point. What ever happened to good old-fashioned for-loops? Yes, we can write things this way, and some people might prefer that alternative.
top: for (e1 of obj1) {
for (e2 of (obj2) {
if (e1.id === e2.tab) {
console.log("found match");
break top;
}
}
console.log("didn't find match);
}
But some people are sure to complain about the non-standard use of break here. Or, we might want to end up with an array of boolean parallel to the input array. In that case, we have to be careful about remembering what matched, at what level.
const matched = [];
for (e1 of obj1) {
let match = false;
for (e2 of obj2) {
if (e1.id === e2.tab) match = true;
}
matched.push(match);
}
We can clean this up and optimize it bit, but that's the basic idea. Notice that we have to reset match each time through the loop over the first object.
I worked on pretty good number of functions like given below
function a(declara,callback) {
x = declara.x;
y = declara.y;
return callback.call(this,[declara]);
}
a({x:1,y:2},function(){ console.log(x+" , "+y); });
but I found thats not actually what callback does, could you please explain me, how can a piping structure be implemented as follows:
a({x:1,y:2}).print()
(Something similar to what jQuery does, also kindly explain me the same!)
If I have understood your question correctly, then
function a(declara) {
x = declara.x;
y = declara.y;
return {print:function(){ console.log(x+" , "+y); }}; //return an object whose one key-value has function inside of it.
}
a({x:1,y:2}).print();