Array confusion with find and includes - javascript

Given the following arrays:
const x = [2, 14, 54, 109, 129, 136, 165, 312, 320, 330, 335, 348, 399, 440, 450, 461, 482, 501, 546, 547, 549, 559, 582, 584, 615, 620, 647, 682];
const y = [539, 681, 682, 683];
Using node v 7.3.0 I observe the following unexpected behavior:
[> x.find(y.includes, y);
undefined
[> y.find(x.includes, x);
682
Sample Snippet:
const x = [2, 14, 54, 109, 129, 136, 165, 312, 320, 330, 335, 348, 399, 440, 450, 461, 482, 501, 546, 547, 549, 559, 582, 584, 615, 620, 647, 682];
const y = [539, 681, 682, 683];
console.log(x.find(y.includes, y))
console.log(y.find(x.includes, x))
However code like x.find(element => y.includes(element)); always finds the element as expected.
I don't get why the two calls that just use find and includes would ever yield different results and would be delighted if someone knows an explanation.

The reason x.find(y.includes, y); is returning undefined is because of arguments passed in function.
Callback of Array.find expects 3 values viz., item, index, array and callback of Array.includes expects 2 arguments, viz., item, fromIndex.
Basically, your current index will be treated as fromIndex in Array.includes and will skip elements before it.
So after four iterations would look like, Array.includes will look for values after 4th element and y does not have them. Hence it returns undefined.

Related

I have an Array I need to push into new Array with object mapping

This is my Array:
[
{
"batchno": "B-PI1-1",
"unitId": 341,
"productName": "Bar Soap",
"productProfileId": 3950,
"qty": 148,
"returnQty": "20",
"rate": 10,
"salesRate": 20,
"unitName": "PC",
"gross": 200,
"net": 200,
"remarks": "sxzxz"
},
{
"batchno": "B-PI4-1",
"unitId": 341,
"productName": "Biscuit",
"productProfileId": 3951,
"qty": 700,
"returnQty": "20",
"rate": 10,
"salesRate": 60,
"unitName": "PC",
"gross": 200,
"net": 200,
"remarks": "zxzxzx"
}
];
I need to push into a new array, but the last one is doubly pushed:
if (this.primengTableHelper.initialRecords.length > 0) {
this.primengTableHelper.initialRecords.map((item: any) => {
console.log('item', item);
this.singleItem.batchNo = item.batchno;
this.singleItem.unitId = item.unitId;
this.singleItem.productName = item.productName;
this.singleItem.productProfileId = item.productProfileId;
this.singleItem.qty = item.qty;
this.singleItem.returnQty = item.returnQty
this.singleItem.rate = item.rate;
this.singleItem.salesRate = item.salesRate;
this.singleItem.unitName = item.unitName;
this.singleItem.gross = item.net;
this.singleItem.net = item.net;
this.singleItem.remarks = item.remarks;
this.createOrEditDamageStockDto.paymentNO = this.voucherNO;
this.createOrEditDamageStockDto.invoiceDate =
this.maxInvoiceDateFilter.toString();
this.createOrEditDamageStockDto.damageStockDetailsListDto
.push(this.singleItem);
});
You keep pushing this.singleItem, which is one object, no matter how many iterations are made. In each iteration that single object is mutated, and then pushed again, resulting in multiple references to the same object.
Instead, make sure to create a new object in each iteration. At the same time avoid all those individual assignments, and use spread syntax instead:
const newItem = {...this.singleItem, ...item};
// Make other changes to `newItem` properties if needed...
// ...
// Push the new object:
this.createOrEditDamageStockDto.damageStockDetailsListDto
.push(newItem);
Not your question, but the following lines make no sense in the loop, since they don't depend on the iterated item:
this.createOrEditDamageStockDto.paymentNO = this.voucherNO;
this.createOrEditDamageStockDto.invoiceDate =
this.maxInvoiceDateFilter.toString();
These statements would always make the same assignment in each iteration. So place them outside that loop.
Note that you shouldn't use .map when you don't use the result. Then just use .forEach. On the other hand, you can use .map to create an array for assigning to this.createOrEditDamageStockDto.damageStockDetailsListDto. Whether that is a good idea in your case, depends on whether that array already exists before the loop, and has content that should stay there.
I'm not sure that I understand the question. You have an array with two objects. Do you simply want a new array with three objects where the last object is identical to the second one? If so, you could use the ES6 spread operator and do this:
const initialRecords = [
{
"batchno": "B-PI1-1",
"unitId": 341,
"productName": "Bar Soap",
"productProfileId": 3950,
"qty": 148,
"returnQty": "20",
"rate": 10,
"salesRate": 20,
"unitName": "PC",
"gross": 200,
"net": 200,
"remarks": "sxzxz"
},
{
"batchno": "B-PI4-1",
"unitId": 341,
"productName": "Biscuit",
"productProfileId": 3951,
"qty": 700,
"returnQty": "20",
"rate": 10,
"salesRate": 60,
"unitName": "PC",
"gross": 200,
"net": 200,
"remarks": "zxzxzx"
}
]
const recordsWithDuplicate = [
...initialRecords,
initialRecords[initialRecords.length - 1]
]
You can read about that here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_array_literals
I hope this helps :-)

Cannot Parse Data From JSON [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I am trying to create a JSON and populate it with some data. The data is a bit complex so I would like to have its "title", "name" and "value".
My issue is that I am not able to get the content from the JSON I created and getting "Uncaught SyntaxError: Unexpected token o" error message. However, if I just pass the json variable to console.log() I can see all the objects contained in the variable.
Please see the code below:
JSON
var json = [
{"title":"rice",
"value":{
"carb": 44.5,
"fat": 0.1,
"cal": 205,
"prot": 4.3
}
},
{"title":"buckwheat",
"value":{
"carb": 20,
"fat": 1,
"cal": 92,
"prot": 3
}
},
{"title":"potato",
"value":{
"carb": 50.5,
"fat": 0.5,
"cal": 225,
"prot": 5.9
},
}
]
JS
var obj = JSON.parse(json);
console.log(obj[0].title);
Maybe I don't understand your question but
JSON.parse()
As first parameter takes some String, text value, converts and returns it as JSON object. Since you have one - you can populate it with your data.
Your json data is not valid.
Valid Example
You can press f12 in Chrome or Mozilla and look console. You can find what is wrong with your JS code.
[
{
"title": "rice",
"value": {
"carb": 20,
"fat": 1,
"cal": 92,
"prot": 3
}
},
{
"title": "buckwheat",
"value": {
"carb": 20,
"fat": 1,
"cal": 92,
"prot": 3
}
},
{
"title": "potato",
"value": {
"carb": 50.5,
"fat": 0.5,
"cal": 225,
"prot": 5.9
}
}
]
Your var "json" is already a javascript object. Just add a semicolon to it and fix the one error (comma after "prot": 5.9}) :
var obj = [
{"title":"rice",
"value":{
"carb": 44.5,
"fat": 0.1,
"cal": 205,
"prot": 4.3
}
},
{"title":"buckwheat",
"value":{
"carb": 20,
"fat": 1,
"cal": 92,
"prot": 3
}
},
{"title":"potato",
"value":{
"carb": 50.5,
"fat": 0.5,
"cal": 225,
"prot": 5.9
}
} ];
You can simply get the values with:
console.log(obj[0].title);
If you want to parse json, save your data in string format.

D3.js "Error: Invalid value for <path> attribute" for moving average

I am trying to create a moving average over the rest of the chart. I am trying to do something similar to this.
However, for my data points I continuously get the error:
"Error: Invalid value for attribute d="M1.2121212121212122,NaNL1.4141414141414141,NaNC1.6161616161616161,NaN,2.0202020202020203,NaN,2.4242424..."
I believe it is because my data isn't formatted correctly, but I don't know how to modify the function to work with my data. My data currently looks like:
var data = [ {"x": 1, "y": 113},
{"x": 6, "y": 38},
{"x": 11, "y": 108},
{"x": 16, "y": 245},
{"x": 21, "y": 155},
{"x": 26, "y": 234},
...
Thanks
Just map your [{x1,y1}, {x2,y2}, ... {xN,yN}] pairs to a [y1, y2, ... yN] series, which is what that moving average function expects:
movingAverageLine(data.map(function(d) { return d.y; }))
Here's a working fiddle: http://jsfiddle.net/yz87b53d/3/
You should accept meetamit's answer since that essentially was the issue.
movingAverageLine(data.map(function(d) { return d.y; }))

how to add data to local storage?

I am working on one game application. Intially I made two loaclstorage, one is userCard and another CompCard and I added 3 cricket players cards details to both the local storage.
My 2 local storage and its deatils :
var user_Card = [["Nixon", "McLean", "West Indies",
45, 314, 0, 1, "12.07", "37.58",
46, 3, 21, 8,
"img/cards/7RBKWQPJAG_NixonMcLean.jpg", 1],
["Brian", "McMillan", "South Africa", 78,
841, 1, 0, "23.36", "36.98", 70, 4, 32, 43,
"img/cards/Y9U5UKA60O_BrianMcMillan.jpg", 2],
["Craig", "McMillan", "New Zealand", 197, 4707, 3,
28, "28.18", "35.04", 49, 3, 20, 44,
"img/cards/WE0NUNG80C_CraigMcMillan.jpg", 3]
];
var comp_Card = [["Geoff", "Miller", "England", 25, 136, 0, 0,
"8.5", "32.52", 25, 3, 27, 4,
"img/cards/7ZPIQXC19H_GeoffMiller.jpg", 4],
["Kyle", "Mills", "New Zealand", 165, 1016,
0, 2, "15.87", "26.74", 235, 5, 25, 40,
"img/cards/P43DTA4ZCX_KyleMills.jpg", 5],
["Minhazul", "Adedin", "Bangladesh", 27, 453, 0, 2,
"18.87", "39.3", 13, 2, 39, 2,
"img/cards/CC8ENY3E09_MinhazulAdedin.jpg", 6]
];
userCard =JSON.parse(localStorage['user_Card']);
compCard =JSON.parse(localStorage['comp_Card']);
When I retrieving all cards details are coming, usercard[0] and compcard [0] is the first card, usercard[1] is the second card, usercard[2] is the third card,
My question is when I play the game, the if usercard wins, I want add the loosing compcard to usercard local storgae. And if compcard wins add the loosing usercard to compcard local storage.
Assume userCard[0] is the first card
compcard[0] is the first card
When I playing the game,if userCard[0] wins, I want to add loosing compcard[0] to localstorage userCard and if compCard[0] wins, I want to add loosing usercard[0] to localstorage compCard
Please provide me the the solution for this.
How you can read from Offline Technologies
Web Storage simply provides a key-value mapping, e.g.
localStorage["name"] = username;. Unfortunately, present
implementations only support string-to-string mappings, so you need to
serialise and de-serialise other data structures. You can do so using
JSON.stringify() and JSON.parse().
so you should try something like this:
var userCard =JSON.parse(localStorage.['user_Card']);
userCard.push(compCard[0]);
localStorage.['user_Card'] = JSON.stringify(userCard));

Adding multiple levels in game created with JSON

For one of my school projects, I have to create a game with Javascript. My Javascript experience is very minimal, and therefore I'm really stuck on how to create multiple levels within my game. With JSON, I load blocks for Mario to walk on:
createBlocks: function () {
console.log('game -> createBlocks');
$.getJSON('js/boxes.json', function (data) {
data.boxes.level1.forEach(function (blockData) {
this.stage.removeChild(this.block.el);
var block = new Block(blockData);
this.block.push(block);
this.stage.addChild(block.el);
}.bind(this));
}.bind(this));
}
With the function "createStars" the game loads another JSON. My goal is to have the game switch to another level with every 5 stars being collected. What is the best way to create this with JSON?
My JSON file for the blocks are created as follow:
{
"boxes": {
"level1": [
{
"x": 0,
"y": 115,
"width": 25,
"height": 25
},
{
"x": 25,
"y": 115,
"width": 25,
"height": 25
}
],
"level2": [
{
"x": 0,
"y": 95,
"width": 25,
"height": 25
}
]
}
}
Please let me know if you need my complete code to answer my question? I can also give a link to the game as it currently is hosted on my own site: http://school.carlavanloon.com/cp/
Furthermore, I'd like the game to stop the time after collecting 20 stars. This will then be the end time for the user of the game.
Many thanks in advance for your reply. And please let me know if I need to give any additional information.
Instead of making your json file around "boxes" you should design the json structure top down,
first load game json, which contains level objects - which contain boxes arrays etc. ie. something like this
var json = {
"game_data": {
"some_global_settings" : {"game_speed": 30, "theme": "dark"},
"level1": {
"boxes": [
{
"x": 0,
"y": 115,
"width": 25,
"height": 25
},
{
"x": 25,
"y": 115,
"width": 25,
"height": 25
}
],
"stars": [
{
"x": 0,
"y": 50,
"width": 25,
"height": 25
},
{
"x": 125,
"y": 120,
"width": 25,
"height": 25
}
],
"player_position" : {"x": 0,"y": 50},
"victory_condition" : {"stars_required" : 5, "time_limit" : "10min"}
},
"level2": {"same structure as above with different data" : 1}
}
}
and then make a level builder function which picks a level object and creates everything in it. To reload a new level, check the number of stars remaining, if its 0, call your createLevel(gamelevel) with n+1 for building the next level.
below is pseudo code sample.
Every time user collects a star, you will check if it was the last star required, and if so, increment the level counter and call level builder function which could be something like this
function buildLevel( levelNr ) {
var gdata = json.game_data["level"+levelNr];
//check if next level exists in game_data object
if (!gdata) {
finishGame();
return false;
}
//next level data exists, so build whats in it
//clear level from previous stuff
clearLevel();//perhaps replace canvas with new one
createBoxes( gdata.boxes);
createStars( gdata.stars);
createPlayer( gdata.player_position);
//everything is ready, add listeners / timers etc, and start the game
}

Categories

Resources