ruby / sort an array of hashes from a defined index - arrays

Having the following array, it defines the sorting :
[300, 450, 345, 23]
And the following array, unsorted :
[
{id: 450, title: 'rand1'},
{id: 23, title: 'rand3'},
{id: 300, title: 'rand0'},
{id: 345, title: 'rand2'},
]
I'd like the first array to be a "rule" to sort my second array (probably by matching the id key).
How can i get achieve this cleanly ?

Naïve approach:
sorter = [300, 450, 345, 23]
input = [
{id: 450, title: 'rand1'},
{id: 23, title: 'rand3'},
{id: 300, title: 'rand0'},
{id: 345, title: 'rand2'},
]
input.sort do |h1, h2|
sorter.index(h1[:id]) <=> sorter.index(h2[:id])
end
#⇒ [
# {:id=>300, :title=>"rand0"},
# {:id=>450, :title=>"rand1"},
# {:id=>345, :title=>"rand2"},
# {:id=>23, :title=>"rand3"}]
or even simper:
input.sort_by { |h| sorter.index(h[:id]) }

Related

how to add array of objects in react native

I have an array of object:
const totalItems = [
{
id: 0,
},
{
id: 1,
item: 'ITEM 1',
fat: 20,
prt: 30,
cho: 0,
cal: 300,
},
{
id: 2,
item: 'ITEM 2',
fat: 10,
prt: 15,
cho: 0,
cal: 150,
},
{
id: 3,
item: 'ITEM 3',
fat: 30,
prt: 10,
cho: 0,
cal: 310,
},
{
id: 4,
item: 'ITEM 4',
fat: 0,
prt: 0,
cho: 30,
cal: 120,
},
];
Now I want to add all the fat objects. I have used reduce() method. But it is not working. I am new at this. Kindly help me
you can map over the array and add the fat.
something like this
let totalFat = 0 ;
totalItems.map((item) => {
// I see there is no fat key value in first object id:0 so this check
// to make sure value exist
item.fat && (totalFat = totalFat + item.fat)
})
console.log(totalFat)
In SO while asking questions please give more details like the code you have tried, it's easier to understand that way.
You can use the method (forEach or map ).

Adding new property using forEach in an array of objects

I have 2 arrays of objects. I would like to add a category property to each object in values, example: 50 should fall in the range 41 to 70
let values = [
{1: 124},
{2: 50},
{3: 65},
{4: 21}
];
let categories = [
{cat: "Category1", min: 5, max: 40},
{cat: "Category2", min: 41, max: 70},
{cat: "Category3", min: 71, max: 130}
];
How do I get my result as, using array method forEach():
[
{1: 124, category: "Category3"},
{2: 50, category: "Category2"},
{3: 65, category: "Category2"},
{4: 21, category: "Category1"}
]
Not an optimized one but satisfies the requirement.
let result = [];
values.forEach(element => {
categories.forEach(col => {
let current = Object.values(element)[0];
if(current >= col.min && current <=col.max){
element["category"] = col.cat;
}
})
result.push(element);
})

Create and Connect nodes just by using "from" and "to" info in React

I am trying to create and connect some nodes using the array below. So in the end there would be 4 nodes connected to each other according to their from and to values. Any ideas on how to do it in React?
roads = [
{
id: 1,
from: {id: 111, name: “Company X”},
to: {id: 222, name: “Station 1“}
},
{
id: 2,
from: {id: 222, name: “Station 1“},
to: {id: 333, name: “Station 2“}
},
{
id: 3,
from: {id: 333, name: “Station 2”},
to: {id: 444, name: “Company Y”}
}
]
I think , you should use Normalized State. It's easy way to create your Nodes ^^

Need help in creating network graph using visjs in angularjs

I need help in making this plunker work something similar to this vis example in angularjs.
I am using <vis-network data="data" options="options"></vis-network> tag and below data and options
data
var nodes = [
{id: 1, label: 'Node 1'},
{id: 2, label: 'Node 2'},
{id: 3, label: 'Node 3'},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'}
];
var edges = [
{from: 1, to: 3},
{from: 1, to: 2},
{from: 2, to: 4},
{from: 2, to: 5}
];
$scope.data = VisDataSet({
nodes: nodes,
edges: edges
});
options
$scope.options = {
autoResize: true,
height: '100%',
width: '100%'
};
There is no console error, what am I missing. Please help.
Your data is plain object, however nodes & edges should be an object of VisDataSet
var nodes = VisDataSet([
{id: 1, label: 'Node 1'},
{id: 2, label: 'Node 2'},
{id: 3, label: 'Node 3'},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'}
]);
var edges = VisDataSet([
{from: 1, to: 3},
{from: 1, to: 2},
{from: 2, to: 4},
{from: 2, to: 5}
]);
$scope.data = {
nodes: nodes,
edges: edges
};
I have updated your plunker here.

Merge two arrays of objects in Ruby

I have an array of objects with unique IDs:
[{id: 1, score: 33}, {id: 23, score: 50}, {id:512, score: 27}, ...]
I also have an array of User records with matching IDs. The user records have "name" but not "score":
[{id: 1, name: "Jon"}, {id: 23, name: "Tom"}, {id: 512, name: "Joey"}, ...]
How can I create a single array with each id, name, and score?
[{id: 1, name: "Jon", score: 33}, {id: 23, name: "Tom", score: 50}, {id: 512, name: "Joey", score: 27}, ...]
I tried merge, combine, filter, etc but haven't found the Ruby function to accomplish this.
Assuming that in users there is always record with corresponding :id from scores:
scores = [{id: 1, score: 33}, {id: 23, score: 50}, {id:512, score: 27}]
users = [{id: 1, name: "Jon"}, {id: 23, name: "Tom"}, {id: 512, name: "Joey"}]
scores = scores.map { |score| score.merge(users.find { |user| user[:id] == score[:id] }) }
# => [{:id=>1, :score=>33, :name=>"Jon"}, {:id=>23, :score=>50, :name=>"Tom"}, {:id=>512, :score=>27, :name=>"Joey"}]
Hope that puts you in proper direction!
You can use an intermediate Hash.
hsh = Hash[ a1.map {|h| [h[:id], h[:score]]} ]
# => {1=>33, 23=>50, 512=>27}
a2.map {|h| h[:score] = hsh[h[:id]]; h}
# => [{:id=>1, :name=>"Jon", :score=>33}, {:id=>23, :name=>"Tom", :score=>50}, {:id=>512, :name=>"Joey", :score=>27}]
If, as in the example, scores[i][:id] = users[i][:id] for all i, and you are using v1.9+ (where key insertion order is maintained), you could write:
scores.zip(users).each_with_object({}) do |(sh,uh),h|
h.update(sh).update(uh)
end
Would I use this? Would you?

Resources