Not sure if I am overcomplicating things but I am trying to get the sum of all the numbers inside this array of arrays:
const frames = [
[2, 0], [4, 2], [6, 0], [2, 4], [1, 5], [7, 0], [5, 2], [7, 0], [2, 6], [8, 1]
]
I am practising using map and reduce to do so:
const score = (frames) =>{
console.log(frames)
let addedScores = frames.map(frame.reduce((previousValue, currentValue) => previousValue + currentValue))
console.log(addedScores)
}
But currently getting this error:
TypeError: 2,04,26,02,41,57,05,27,02,68,1 is not a function
at Array.map (<anonymous>)
at score (/Users/x/Desktop/Programming/devacademy/bootcamp/week1/preparation/bowling-kata/game.js:8:28)
at Object.<anonymous> (/Users/x/Desktop/Programming/devacademy/bootcamp/week1/preparation/bowling-kata/game.js:17:1)
Here is a fiddle version.
Any advice and explanation would be greatly appreciated
You are almost there on this one! If you look at the stack trace for the error you are facing, you will see that an error is thrown by Array.map function, and namely that "stuff" (i.e 2,04,26,02,41,57,05,27,02,68,1) is "not a function".
The map higher-order function expects a function that it will map accross the elements of frames.
What you want is something like this:
//...
let addedScores = frames.map((frame) => frame.reduce((previousValue, currentValue) => previousValue + currentValue))
//...
Here I have only converted your addedScores expression to pass an anonymous function: (frame) => { ... } to the map function.
Hope this helps!
The resulting shape for addedScores would be: [2, 6, 6, 6, 6, 7, ...], which is the sum of each pair of numbers in frames.
Related
Assume i have created a function function findInputGiven(){} and i called it somewhere below twice findInputGiven([1, 2], [3, 4]), findInputGiven([1, 2], [3, 4], [5, 6]). This function can be called with multiple inputs, i dont know how many inputs will be available in my findInputGiven function. How can i get the number of inputs given to call function.
My task is to return an array of all numbers of given arrays. If the function is called like findInputGiven([1, 2], [5, 6]), then i should return [1, 2, 5, 6].
My task is to return an array of all numbers of given arrays
What you can do is use rest parameters to get an array of all arguments and then return the flattened result. You can still get a count of the arguments if required but for this task, I don't think you'll need it.
function findInputGiven(...arrays) {
// you can get the argument count if you need it
console.log(`Got ${arrays.length} argument(s)`)
// return the flattened result
return arrays.flat()
}
console.info(findInputGiven([1, 2], [3, 4]))
console.info(findInputGiven([1, 2], [3, 4], [5, 6]))
.as-console-wrapper { max-height: 100% !important }
If you are not familiar with Rest parameters, Array.prototype.flat of ES6 feature along with don't want to "transpile" your code.
You can achieve it by using arguments.
function findInputGiven() {
const numberOfInputs = arguments.length;
console.log(`Number of inputs: ${numberOfInputs}`);
let result = [];
Object.values(arguments).forEach(function(item, index){
if(Array.isArray(item))
result = result.concat(item);
else
result.push(item);
});
return result;
}
console.log(findInputGiven([1, 2], [3, 4]))
console.log(findInputGiven([1, 2], [3, 4], [5, 6], 7))
More detailed explanation:
As you may know, rest parameters & flat() aren't supporting IE. So that is where transpiler come from :)
I have an array of arrays. How can I get an array with a nested array whose elements have a unique order?
What I have:
[[1, 2], [1, 2, 3], [3, 4]]
Expected Output:
[[1, 2, 3], [3, 4]]
I think, that I can format to JSON, and get my result with filter and indexOf ,I have tried this:
var unique = x2.map(ar=>JSON.stringify(ar).replace(/[\[\]']+/g,''))
.filter((itm, idx, arr) => arr.indexOf(itm) === idx);
Here is my try, I first sorted the array by its length then applied filter and match the index position by making use of every and includes. Here is an example:
var example = [[1, 2, 35, 7], [1, 2, 3], [35, 7], [3, 4], [4]];
var result = example.sort((a,b)=>b.length-a.length).filter((k,i,self)=>self.findIndex(p=>k.every(l=>p.includes(l)))==i);
console.log(result);
I hope this helps.
I use the method of Array.prototype.join for multidimensional array, but I get curious result. I try to see the bottom implementation of Array.prototype.join, it show me the native code
[1,2,3,4,5,6,7,8].join('')
[1, [2], [3, [4, [5]]], [6, [7, [8]]]].join('');
I expect the output of
[1,[2],[3,[4,[5]]],[6,[7,[8]]]].join('')
to be
12345678
but the actual output is
123,4,56,7,8
.join calls .toString() on each element to turn it into a string, and Array.prototype.toString() by default concatenates all its elements with a ,.
console.log([1, 2, 3].toString());
Like others already said, toString is called upon the array. However, by providing a separator it will only join the array on which you call the method with that separator.
[
1,
[2],
[3, [4, [5]]],
[6, [7, [8]]]
].join("")
Will simply join the first level elements together, calling toString on elements that aren't a string.
1.toString() + "" +
[2].toString() + "" +
[3, [4, [5]]].toString() + "" +
[6, [7, [8]]].toString()
Where the "" is the separator. Resulting in 123,4,56,7,8 where 3,4,5 is the first nested array and 6,7,8 the second (with more than 1 element). If you'd like to join the elements recursive you could create your own method.
Array.prototype.deepJoin = function (separator) {
return this
.map(e => Array.isArray(e) ? e.deepJoin(separator) : e)
.join(separator);
};
var array = [1, [2], [3, [4, [5]]], [6, [7, [8]]]];
console.log(array.join());
console.log(array.deepJoin());
console.log(array.join(""));
console.log(array.deepJoin(""));
console.log(array.join(" - "));
console.log(array.deepJoin(" - "));
The join method also invoke toString() on each element.
You have
[2].toString() -> 2
[3, [4, 5]].toString() -> 3,4,5
And so on. The toString method on an array never preserves square parenthesis
I am learning to write reducers for arrays. For example, one of the reducers changes array elements from integers to arrays.
Original state:
[0, 3, 5, 3, 9, 8]
Action:
case ADD_NEST:
return state.map(i => [i, action.payload]);
New state:
[[0, 0], [3, 0], [5, 0], [3, 0], [9, 0], [8, 0]]
I'm trying to write a reducer that would change the second element of sub-arrays based on the condition of the first one. (eg, if the first element of the subarray is greater than 3, change the second element to 1).
[[0, 0], [3, 0], [5, 1], [3, 0], [9, 1], [8, 1]]
so far I have (not much as I'm stuck):
case SET_BIT:
return state.map(i => (i[0] > 3 ? ??? : i));
Thank you for advice!
Like this?
case SET_BIT:
return state.map(i => (i[0] > 3 ? [i[0], i[1] + 1] : i));
Although, that's a bit weird/dangerous. What happens if SET_BIT gets dispatched when your state of that reducer is still a flat array? Then the above code will crash. Then you would have to do something like:
case SET_BIT:
return state.map(i => (
Array.isArray(i) && i[0] > 3
? [i[0], i[1] + 1]
: i
));
I don't know the details of what you are trying to do here, but generally speaking I think it's best to keep the structure of the state of a reducer consistent. I tend to avoid nested structures in the state of my redux store because I try to keep the state of my redux store as normalized as I can. That makes reducers a lot easier to maintain. If I need to nest stuff for my views I usually do that in the selectors.
But again, I lack context, so not sure if any of this advice is relevant to you. :-)
Assuming this JSON object:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
The "set2" property may be retrieved like so:
obj["set2"]
Is there a way to retrieve the "set2" property by index? It is the second property of the JSON object. This does not work (of course):
obj[1]
So, let's say that I want to retrieve the second property of the JSON object, but I don't know its name - how would I do it then?
Update: Yes, I understand that objects are collections of unordered properties. But I don't think that the browsers mess with the "original" order defined by the JSON literal / string.
Objects in JavaScript are collections of unordered properties. Objects are hashtables.
If you want your properties to be in alphabetical order, one possible solution would be to create an index for your properties in a separate array. Just a few hours ago, I answered a question on Stack Overflow which you may want to check out:
Iterating over a JavaScript object in sort order based on particular key value of a child object
Here's a quick adaptation for your object1:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var index = [];
// build the index
for (var x in obj) {
index.push(x);
}
// sort the index
index.sort(function (a, b) {
return a == b ? 0 : (a > b ? 1 : -1);
});
Then you would be able to do the following:
console.log(obj[index[1]]);
The answer I cited earlier proposes a reusable solution to iterate over such an object. That is unless you can change your JSON to as #Jacob Relkin suggested in the other answer, which could be easier.
1 You may want to use the hasOwnProperty() method to ensure that the properties belong to your object and are not inherited from Object.prototype.
I know this is an old question but I found a way to get the fields by index.
You can do it by using the Object.keys method.
When you call the Object.keys method it returns the keys in the order they were assigned (See the example below). I tested the method below in the following browsers:
Google Chrome version 43.0
Firefox version 33.1
Internet Explorer version 11
I also wrote a small extension to the object class so you can call the nth key of the object using getByIndex.
// Function to get the nth key from the object
Object.prototype.getByIndex = function(index) {
return this[Object.keys(this)[index]];
};
var obj1 = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var obj2 = {
"set2": [4, 5, 6, 7, 8],
"set1": [1, 2, 3],
"set3": [9, 10, 11, 12]
};
log('-- Obj1 --');
log(obj1);
log(Object.keys(obj1));
log(obj1.getByIndex(0));
log('-- Obj2 --');
log(obj2);
log(Object.keys(obj2));
log(obj2.getByIndex(0));
// Log function to make the snippet possible
function log(x) {
var d = document.createElement("div");
if (typeof x === "object") {
x = JSON.stringify(x, null, 4);
}
d.textContent= x;
document.body.appendChild(d);
}
No, there is no way to access the element by index in JavaScript objects.
One solution to this if you have access to the source of this JSON, would be to change each element to a JSON object and stick the key inside of that object like this:
var obj = [
{"key":"set1", "data":[1, 2, 3]},
{"key":"set2", "data":[4, 5, 6, 7, 8]},
{"key":"set3", "data":[9, 10, 11, 12]}
];
You would then be able to access the elements numerically:
for(var i = 0; i < obj.length; i++) {
var k = obj[i]['key'];
var data = obj[i]['data'];
//do something with k or data...
}
Simple solution, just one line..
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
obj = Object.values(obj);
obj[1]....
Here you can access "set2" property following:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var output = Object.keys(obj)[1];
Object.keys return all the keys of provided object as Array..
Jeroen Vervaeke's answer is modular and the works fine, but it can cause problems if it is using with jQuery or other libraries that count on "object-as-hashtables" feature of Javascript.
I modified it a little to make usable with these libs.
function getByIndex(obj, index) {
return obj[Object.keys(obj)[index]];
}
You could iterate over the object and assign properties to indexes, like this:
var lookup = [];
var i = 0;
for (var name in obj) {
if (obj.hasOwnProperty(name)) {
lookup[i] = obj[name];
i++;
}
}
lookup[2] ...
However, as the others have said, the keys are in principle unordered. If you have code which depends on the corder, consider it a hack. Make sure you have unit tests so that you will know when it breaks.
"""
This could be done in python as follows.
Form the command as a string and then execute
"""
context = {
"whoami": "abc",
"status": "0",
"curStep": 2,
"parentStepStatus": {
"step1":[{"stepStatus": 0, "stepLog": "f1.log"}],
"step2":[{"stepStatus": 0, "stepLog": "f2.log"}]
}
}
def punc():
i = 1
while (i < 10):
x = "print(" + "context" + "['parentStepStatus']" + "['%s']"%("step%s")%(i) + ")"
exec(x)
i+=1
punc()
There is no "second property" -- when you say var obj = { ... }, the properties inside the braces are unordered. Even a 'for' loop walking through them might return them in different orders on different JavaScript implementations.
it is quite simple...
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
jQuery.each(obj, function(i, val) {
console.log(i); // "set1"
console.log(val); // [1, 2, 3]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
var obj = {
"set1": [
1,
2,
3
],
"set2": [
4,
5,
6,
7,
8
],
"set3": [
9,
10,
11,
12
]
};
var outputKeys = Object.keys(obj)[1];
var outputValues = Object.values(obj)[1];
//outputKeys would be "set2"`enter code here`
//outPutValues would be [4,5,6,7,8]
My solution:
Object.prototype.__index=function(index)
{var i=-1;
for (var key in this)
{if (this.hasOwnProperty(key) && typeof(this[key])!=='function')
{++i;
}
if (i>=index)
{return this[key];
}
}
return null;
}
aObj={'jack':3, 'peter':4, '5':'col', 'kk':function(){alert('hell');}, 'till':'ding'};
alert(aObj.__index(4));