Difference between _.forEach and _.forOwn in lodash - foreach

What is the difference between these two methods when iterating over an object?

The difference lies in that if the collection over which you are iterating is an object which has a length property, then the _.forEach() will iterate over it as if it were an array, whereas the _.forOwn() will iterate over it like an object.
Assume you have the object:
a = {
x: 100,
y: 200,
length: 2
}
If you iterate over it as:
_.forEach(a, function(val, key) {
console.log('a[' + key + '] = ' + val);
});
you'll get output:
a[0] = undefined
a[1] = undefined
whereas iterating over it with _.forOwn() you'll get the more reasonable:
a[x] = 100
a[y] = 200
a[length] = 2

Related

I don't Understand "How Lua save data on the same variable when we Iterate over it"

I know Lua remember value in the same field/function with the Same defined Variable. but I still lack the concept behind it. Let's say I'see Int Variable = 2 which can be modify if we iterate over it Int variable = 8
Same logic I was applying on the Code. I got the results, but I didn't understand the concept behind it.
You Can see in my Code I was saving some value in Var x and saveX
and I was doing saveX = x from my logic The value of x should be saved inside saveX instead it was saving the loop value as I'm applying over it. Why is that?
-- Graphical Representation of table1
--[[ { { {},{},{},{} },
{ {},{},{},{} },
{ {},{},{},{} },
{ {},{},{},{} } } ]]
_Gtable1 = {}
for y = 1, 4 do
table.insert(_Gtable1, {})
for x = 1, 4 do
table.insert(_Gtable1[y], {
x = (x - 1) * 10, --Coordinate value of X
y = (y - 1) * 10, --Coordinate value of Y
-- what if i want to save Coordinate value on another variable How should i do?
saveX = x, -- Saving Loop X
saveY = y, -- Saving Loo Y
t = "Check" -- to Debug
})
end
end
ti = _Gtable1
for y = 1, 4 do
for x = 1, 4 do
tim = ti[y][x]
-- print(tim.saveX) -- output 1, 2, 3, 4
print(tim.x) -- output 0, 10, 20, 30
end
end
I hope I understood the question:
Let's simplify the example:
local t = {
x = 10,
y = x,
}
You assume t.y is 10, because you declared it a line before that? But it is nil here, because x = 10, is no variable. It's part of the table constructor and can not be referenced in the same constructor. Check out https://www.lua.org/pil/3.6.html for more details.
After the constructor has finished, you can access that as t.x (not x!).
Now for your example, you need to move (x - 1) * 10 outside the constructor, e.g.: local tempX = (x - 1) * 10. Then use tempX inside the constructor. Or you can set your values individually, e.g. _Gtable1[y][x].saveX = _Gtable1[y][x].x. I would prefer the former.

How to update/reload table key values

How can i update a key value using another key value as variable which is inside the same table?
local t = {}
t.playerPosition = {x = 0, y = 0, z = 0}
t.positions = {t.playerPosition.x + 1, t.playerPosition.y + 1, t.playerPosition.z + 1}
Then few lines later i update playerPosition
t.playerPosition = {x = 125, y = 50, z = 7}
And then if i print out...
result
t.positions[1] -- outputs 1
t.positions[2] -- outputs 1
t.positions[3] -- outputs 1
expected result
t.positions[1] -- outputs 126
t.positions[2] -- outputs 51
t.positions[3] -- outputs 8
As you can see key positions isnt updating, what could i do to make it possible?
t.positions = {t.playerPosition.x + 1, t.playerPosition.y + 1, t.playerPosition.z + 1}
In the above line, the expressions are evaluated once, and the resulting values are assigned to fields of the subtable. After this point, changes to the fields of t.playerPosition will not cause a reflected change in t.positions.
Metatables can be used to enable such behaviour, by dynamically calculating results when accessing the fields of t.positions.
local t = {}
t.playerPosition = { x = 0, y = 0, z = 0 }
t.positions = setmetatable({}, {
__newindex = function () return false end,
__index = function (_, index)
local lookup = { 'x', 'y', 'z' }
local value = t.playerPosition[lookup[index]]
if value then
return value + 1
end
end
})
print(t.positions[1], t.positions[2], t.positions[3])
t.playerPosition = {x = 125, y = 50, z = 7}
print(t.positions[1], t.positions[2], t.positions[3])

add value afterwards to key in table lua

Does someone know how to add an value to an key which already has an value ?
for example:
x = {}
x[1] = {string = "hallo"}
x[1] = {number = 10}
print(x[1].string) --nil
print(x[1].number) --10
It should be possible to print both things out. The same way how it is here possible:
x[1] = { string = "hallo" ; number = 10}
I just need to add some informations afterwards to the table and especially to the same key.
Thanks!
x = {} -- create an empty table
x[1] = {string = "hallo"} -- assign a table with 1 element to x[1]
x[1] = {number = 10} -- assign another table to x[1]
The second assignment overwrites the first assignment.
x[1]["number"] = 10 or short x[1].number = 10 will add a field number with value 10 to the table x[1]
Notice that your x[1] = { string = "hallo" ; number = 10} is acutally equivalent to
x[1] = {}
x[1]["string"] = "hallo"
x[1]["number"] = 10

Convert string into array and do operations

I have a string like: "1234567334535674326774324423". I need to create a method to do the following:
Make an array consisting of digits in the string like [1, 2, 3, ..., 2, 3]
Sum all the odd positions of the array
Sum all the even positions of the array
Multiply the odd sum by 3
Sum step 4 and step 3.
Get the minimum number to sum to step 5 to get the sum that is a multiple of 5.
I don't know how to solve this with rails. If anyone can help me, I would be glad.
I have this:
barcode_array = #invoice.barcode.each_char.map {|c| c.to_i}
impares = [barcode_array[0]] + (1...barcode_array.size).step(2).collect { |i| barcode_array[i] }
pares = (2...barcode_array.size).step(2).collect { |i| barcode_array[i] }
suma_impares = impares.inject(:+)
mult_impares = suma_impares * 3
suma total = mult_impares + pares
I solved it. Here is the code if anyone needs it:
barcode_array = #invoice.barcode.each_char.map {|c| c.to_i}
impares = [barcode_array[0]] + (1...barcode_array.size).step(2).collect { |i| barcode_array[i] }
pares = (2...barcode_array.size).step(2).collect { |i| barcode_array[i] }
suma_impares = impares.inject(:+).to_i
mult_impares = suma_impares * 3
suma_pares = pares.inject(:+).to_i
suma_total = mult_impares + suma_pares
verificador = 10 - (suma_total - (suma_total / 10).to_i * 10)
#invoice.barcode = #invoice.barcode.to_s + verificador.to_s
I'm not sure what you mean in step 6, but here's how I would tackle 1-5:
s = '1234567334535674326774324423'
a = s.chars.map(&:to_i) # convert to an array of integers
odd_sum = 0
even_sum = 0
# sum up odds and evens
a.each_with_index {|n, i| n.even? ? even_sum += n : odd_sum += n}
total = even_sum + odd_sum * 3

Plotting a line using d3 and an JSON data object passed from rails

I'm pushing the boundaries of experience here and cant see what I am doing wrong.
I'm pulling a bunch of data from a DB in rails, converting it to JSON and trying to plot it in d3.
The data is a simple JSON of {date => number} and the data is fine.
I'm doing something wrong with d3 in the loop at the bottom of the code but cant see what.
The axes plot fine but I can't get the line to draw.
Here is my code:
var data = <%= #signups.to_json.html_safe %>;
var date, signups
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%d-%b-%Y").parse;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.x(date)
.y(signups)
.interpolate("linear");
var svg = d3.select(".container").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Find range of data for domain
var min_date = Infinity, max_date = -Infinity;
var min_signups = Infinity, max_signups = -Infinity;
var x;
$.each(data, function(key, value) {
temp = parseDate(key)
if( temp < min_date) min_date = temp;
if( temp > max_date) max_date = temp;
if( +value < min_signups) min_signups = +value;
if( +value > max_signups) max_signups = +value;
});
x.domain([min_date, max_date]);
y.domain([0, max_signups]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Price ($)");
svg.append("path")
$.each(data, function(key, value) {
date = parseDate(key);
signups = value;
d3.select("path")
.append("svg")
.attr("d", d3.svg.line()
.x(date)
.y(signups)
.interpolate("linear"));
});
Any help would be greatly appreciated
The D3 way would be to pass all your data to a suitable line generator. This is fairly simple in your case, you just need to convert the object that contains all the data to an array that D3 can work with using d3.entries().
var line = d3.svg.line()
.x(function(d) { return x(parseDate(d.key)); })
.y(function(d) { return y(d.value); });
svg.selectAll("path").data([d3.entries(data)])
.enter().append("path").attr("d", line);
As you have only a single line, you could also use .datum() to bind the data, but using .data() leaves you the option of passing in data for more lines later.
Complete jsfiddle here. When modifying this, make sure that you create the line before adding the axes, otherwise D3's data matching won't work with the default matching and you won't get any lines. To fix this, you could supply a matching function, but to start with it's much easier to keep to this order.

Resources