Using d3js sort an array of arrays - arrays

I have an array where each element in the array (representing a Supreme Court Chief Justice) contains an array of data points (the Chief Justice's name, number of disputes and year).
For each element in the top-level array, I need to sort the lower-level array in ascending order by year.
I attempted to sort year by ascending order using the following:
nested_data.forEach(function(d) {
d.values.sort(d3.ascending(d.values.year));
});
But it did not sort the lower-level array in ascending order by year.
Here is the console.log of my nested data to show its structure.
Array[5]
0:Object
key:"Vinson"
values:Array[7]
0:Object
chief:"Vinson"
disputes:142
year:Tue Jan 01 1946 00:00:00 GMT+0800 (CST)
1:Object
2:Object
3:Object
4:Object
5:Object
6:Object
1:Object
key:"Warren"
values:Array[16]
2:Object
key:"Burger"
values:Array[17]
3:Object
key:"Rehnquist"
values:Array[19]
4:Object
key:"Roberts"
values:Array[11]
How can I sort the lower-level array in ascending order by year?

This is the function:
nested_data.forEach(function(d) {
d.values.sort(function(a, b) {
return d3.ascending(+a.year, +b.year)
});
});
Your original function had two problems:
Since you're sorting the values arrays, you don't need to repeat values in the compareFunction
When specified, compareFunction uses two parameters, normally named a and b. You have to put d3.ascending inside compareFunction. Have a look here.
Here is a demo with a bogus data:
var data = [{
key: "foo",
values: [{
chief: "Bob",
year: 1982
}, {
chief: "Tom",
year: 1977
}, {
chief: "Carla",
year: 2010
}, {
chief: "Ana",
year: 1999
}]
}, {
key: "bar",
values: [{
chief: "Bill",
year: 2009
}, {
chief: "Ted",
year: 2014
}]
}, {
key: "baz",
values: [{
chief: "Fred",
year: 1998
}, {
chief: "Su",
year: 1992
}, {
chief: "Charlie",
year: 1999
}, {
chief: "Alice",
year: 1979
}]
}, ];
data.forEach(function(d) {
d.values.sort(function(a, b) {
return d3.ascending(+a.year, +b.year)
});
});
console.log(data);
<script src="https://d3js.org/d3.v4.min.js"></script>

Related

Split in MongoDB

{
_id: ObjectId("624ab34913b144c54b3c9ad4"),
PlayerName: 'Novak Djokovic',
Born: 'Belgrade, Serbia',
Height: 188,
Hand: 'Right-Handed, Two-Handed Backhand',
LinkPlayer: 'https://www.atptour.com/en/players/novak-djokovic/d643/player-activity?year=all&matchType=Singles',
Tournament: 'Tokyo Olympics',
Location: 'Tokyo, Japan',
Date: '2021.07.26 - 2021.08.01',
Ground: 'Hard',
Prize: '',
GameRound: 'Quarter-Finals',
GameRank: 69,
Oponent: 'Kei Nishikori',
WL: 'W',
Score: '62 60'
}
This is an example of a collection I have to work on.
How can I separate the location, and have one field called city for the first value and another one for country with the second value?
I know I have to use aggregate - db.atpplayers.aggregate() in this case - and with the function $split.
I got to this one db.atpplayers.aggregate([{$project:{city:{$split:["$Location",","]}}}]), but I got this:
{
_id: ObjectId("624ab34913b144c54b3c9ad4"),
city: [ 'Tokyo', ' Japan' ]
}
Using the same aggregation you have you only need to add another stage to use the first value of the array as City and the second as Country.
You can use $first and $last to achieve that:
{
"$project": {
"city": {
"$first": "$city"
},
"country": {
"$last": "$city"
}
}
}
Example here

Sum the values for all similar hash keys Ruby

Below is my code. It works (yes!), but it requires 3 loops (yikes!). Still new to coding, but I am wondering if there is a more efficient, dryer, or simply better looking way of producing the desired result. The goal is to sum the values for all similar car makes. I then store the values in a hash for each make ({"Honda" => 12400}) and then store the hashes within an array. Not sure if this is the best way to go about it, but assume down the line you will want to access the values depending on the make. I also want to avoid hard coding anything - assume there are 100 different makes. All advice welcome!
cars = [
{
make: "Nissan",
model: "Model",
year: 2017,
value: 5000
},
{
make: "Toyota",
model: "Corolla",
year: 1997,
value: 1000
},
{
make: "Toyota",
model: "Camry",
year: 2006,
value: 3500
},
{
make: "Honda",
model: "Accord",
year: 2001,
value: 5000
},
{
make: "Toyota",
model: "Tacoma",
year: 2001,
value: 2000
},
{
make: "Honda",
model: "Civic",
year: 2001,
value: 1200
},
{
make: "Honda",
model: "Civic",
year: 2005,
value: 2200
},
{
make: "Honda",
model: "Accord",
year: 2010,
value: 4000
},
{
make: "Nissan",
model: "Altima",
year: 2017,
value: 10000
}
]
#GOAL
#Sum the values for all similar makes and store in an array with a nested hash
# sums_array = [{all_hondas: total_sum}, {all_toyotas: total_sum}]
total_value = 0
car_makes = []
cars.each{|car|
#creates a hash with a car's make as the key and 0 as the value
car_hash = {car[:make] => total_value}
#shovels car_hash into an array if it does not already exist within the array
unless car_makes.include? car_hash
car_makes << car_hash
end
}
values_array = []
car_makes.each {|make|
make.each {|k, v|
cars.each{|car|
if car[:make] == k
v += car[:value]
end
}
values_array << {k => v}
}
}
p values_array
#values_array = [{"Nissan"=>15000}, {"Toyota"=>6500},{"Honda"=>12400}]
Or in one iteration:
cars.each_with_object(Hash.new(0)) { |car, hash| hash[car[:make]] += car[:value] }
#=> {"Nissan"=>15000, "Toyota"=>6500, "Honda"=>12400}
Docs about Enumerable#each_with_object and Hash#new with a default

How to update multiple objects in a single collection of mongodb?

I have one collection in mongodb as given below -
[
{
id: "1",
itemName: "pen",
quantity: 10
},
{
id: "2",
itemName: "notebook",
quantity: 20
},
{
id: "3",
itemName: "book",
quantity: 30
}
]
I have to update this collection in one go. From UI I am getting the request array as -
[
{
"id": "1",
"quantity": 12
},
{
"id":"2",
"quantity": 13
}
]
I need to update the corresponding objects. I can run it in a for loop and using
db.collection.update()
I can update it. But is there any way to pass the whole array to update the corresponding objects in one go?

How to check before updating an array element in MongoDB/NodeJS

In my sample document, I have a campaign document that contains the _id of the document and an importData array. importData is an array of objects containing a unique date and source value.
My goal is to have an object updated with a unique date/source pair. I would like to have the new object replace any matching object. In the example below, Fred may have originally donated a TV, but I want my application to update the object to reflect he donated both a TV and a radio.
// Events (sample document)
{
"_id" : "Junky Joe's Jubilee",
"importData" : [
{
"date": "2015-05-31",
"source": "Fred",
"items": [
{item: "TV", value: 20.00},
{item: "radio", value: 5.34}
]
},
{
"date": "2015-05-31",
"source": "Mary",
"items": [
{item: "Dresser", value: 225.00}
]
}
]
}
My original thought was to do something like the code below, but not only am I updating importData with Fred's donations, I'm also blowing away anything else in the importData array:
var collection = db.collection("events");
collection.update(
{_id: "Junky Joe's Jubilee",
importData: {
date: "2015-05-31",
source: 'Fred'
},
}, // See if we can find a campaign object with this name
{
$set:
{"importData":
{
date: "2015-05-31",
source: 'Fred',
items: [
{item: "TV", value: 20.00},
{item: "radio", value: 5.34}
]
}
}
},
{upsert: true}); // Create a document if one does not exist for this campaign
When I tried pushing (instead of $set), I was getting multiple entries for the date/source combos (e.g. Fred would appear to have donated two items multiple times on "2015-05-31").
How would I go about doing that with the MongoDB native driver and NodeJS?
Try this
var collection = db.collection("events");
collection.update(
{_id: "Junky Joe's Jubilee",
importData: {
date: "2015-05-31",
source: 'Fred'
},
}, // See if we can find a campaign object with this name
{
$set:
{"importData.$":
{
date: "2015-05-31",
source: 'Fred',
items: [
{item: "TV", value: 20.00},
{item: "radio", value: 5.34}
]
}
}
},
{upsert: true}); // Create a document if one does not exist for this campaign
According to the documentation under Array update operators this should only modify the first element in the array, which matches the query.

Filter unique values from a JSON

I am using angularjs for my page. I want to filter the values from the JSON object, So that no redundancy exists. But I didn't find any way to get the unique values from angular ng-repeat. Is there anyway to do that?
Ok, Here is some description about the question. I have a JSON in this format. This JSON I am getting from a service. So we cant expect how the repeated data occure.
result = [
{
_id: "500004",
subject: "Complete the task",
date: "25 Aug, 2013"
},
{
_id: "500004",
subject: "Complete the task",
date: "25 Aug, 2013"
},
{
_id: "500005",
subject: "Attend to the event",
date: "2 Jan, 2013"
},
{
_id: "500065",
subject: "Some task deadline",
date: "20 Sep, 2013"
},
{
_id: "500004",
subject: "Complete the task",
date: "25 Aug, 2013"
}
]
I want the output JSON to be with no repeated elements, So that my output will be something like this
result = [
{
_id: "500004",
subject: "Complete the task",
date: "25 Aug, 2013"
},
{
_id: "500005",
subject: "Attend to the event",
date: "2 Jan, 2013"
},
{
_id: "500065",
subject: "Some task deadline",
date: "20 Sep, 2013"
}
]
You can make use of Angular UI which has the unique filter defined.
The source can be found here.
Basically, you can then make use of the filter as follows:
<div ng-repeat="item in result | unique:'_id'">
//Body here
</div>
You can use 'unique'(aliases: uniq) filter in angular.filter module (https://github.com/a8m/angular-filter)
usage: colection | uniq: 'property'
you can filter by nested properties to : colection | uniq: 'property.nested_property'
So you can do something like that..
function MainController ($scope) {
$scope.orders = [
{ id:1, customer: { name: 'foo', id: 10 } },
{ id:2, customer: { name: 'bar', id: 20 } },
{ id:3, customer: { name: 'foo', id: 10 } },
{ id:4, customer: { name: 'bar', id: 20 } },
{ id:5, customer: { name: 'baz', id: 30 } },
];
}
HTML: We filters by customer id, i.e remove duplicate customers
<th>All customers list: </th>
<tr ng-repeat="order in orders | unique: 'customer.id'" >
<td> {{ order.customer.name }} , {{ order.customer.id }} </td>
</tr>
result:
All customers list:
foo 10
bar 20
baz 30
var data = [
{
_id: "500004",
subject: "Complete the task",
date: "25 Aug, 2013"
},
{
_id: "500004",
subject: "Complete the task",
date: "25 Aug, 2013"
},
{
_id: "500005",
subject: "Attend to the event",
date: "2 Jan, 2013"
},
{
_id: "500065",
subject: "Some task deadline",
date: "20 Sep, 2013"
},
{
_id: "500004",
subject: "Complete the task",
date: "25 Aug, 2013"
}
]
var uniqueNames = [];
var uniqueObj = [];
for(i = 0; i< data.length; i++){
if(uniqueNames.indexOf(data[i]._id) === -1){
uniqueObj.push(data[i])
uniqueNames.push(data[i]._id);
}
}
console.log('uniqueObj',uniqueObj)
http://jsfiddle.net/C97DJ/165/

Resources