beetlejuice
beetlejuice

Reputation: 59

Merge objects that share a common key or value

I'm loading in a big CSV to work with in javascript -- to create SVG elements from. There is a property in the variable called code. In the CSV, there is a column called SPECIES. "Code" and "SPECIES" contain the same letter codes. I'd like to be able to compare the data in the CSV to the var trees, and if for a particular record in the CSV, the "SPECIES" field is the same as the "code" value in the variable, I want to return the "common" value from the variable. The CSV file has 150,000 records, which is why I don't want to add another column with common name to it.

Here is part of the variable (there are 54 objects in all):

var trees = [
        { code: 'ACPL', 
          common: 'Norway Maple', 
          genus: 'Acer', 
          species: 'platanoides', 
          family: 'Sapindaceae', 
          color: '#00567e'
        },
        { code: 'ACRU', 
          common: 'Red Maple', 
          genus: 'Acer', 
          species: 'rubrum', 
          family: 'Sapindaceae', 
          color: '#0084ff'
        },
        { code: 'ACSA1', 
          common: 'Silver Maple', 
          genus: 'Acer', 
          species: 'saccharinum', 
          family: 'Sapindaceae', 
          color: '#c3c3c3'
        }
];

Here is part of the data.csv (150,000 records total here):

DIAMETER,SPECIES,longitude,latitude
15,ACPL,-73.935944,40.668076
22,ACPL,-73.934644,40.667189
28,ACSA1,-73.941676,40.667593
27,ACPL,-73.935095,40.666322
9,ACRU,-73.941297,40.667574
27,ACPL,-73.935149,40.666324
19,ACRU,-73.933664,40.666244

Here is what I've tried, which isn't working:

var treeCode = trees.forEach(function(each) { return each.code; }); // returns the value of "code" for each object in the trees variable
var treeCommon = trees.forEach(function(each) { return each.common; }); // returns the value of "color" for each object in the trees variable

var tip = d3.tip() // d3.tip is a tooltip library for D3.js
        .attr('class', 'd3-tip')
        .offset([-10, 0])
        .html(function(d){if (d.SPECIES == treeCode){  // the data from the csv was loaded in earlier, and d.SPECIES returns the "SPECIES" field
            return treeCommon}
        })

Any thoughts about what needs to be done would be greatly appreciated! Let me know if I can clarify anything. The full code is here: https://github.com/jhubley/street-trees/blob/master/index.html You can see in that code that there's a looong if/else statement with hexadecimal colors. That's another example of where I want to use this approach. Thank you for looking!

Upvotes: 1

Views: 933

Answers (1)

Patrick Gunderson
Patrick Gunderson

Reputation: 3281

There's some great documentation for underscore at http://underscorejs.org/. D3 is a fairly robust lib so I bet some of these functions are already built in to D3 as well.

So to clarify, you want to run through the records in the CSV and pull the corresponding data from the trees object. Here's how I would do this with underscore:

// Information about each tree type
var treeInfo = [
    { 
        code: 'ACPL', 
        common: 'Norway Maple', 
        genus: 'Acer', 
        species: 'platanoides', 
        family: 'Sapindaceae', 
        color: '#00567e'
    },
    ...
];

// imported from CSV
var treeList = [
    {
        DIAMETER: 15,
        SPECIES: "ACPL",
        longitude: -73.935944,
        latitude: 40.668076
    }
    ...
]

// loop through the imported list of trees
_.each(treeList, function(){
    // _.each() makes `this`` refer to the object in the list as it loops through
    // find the info for this tree species
    var info = _.findWhere(treeData, {"code": this.SPECIES});
    // insert the keys and values from the info object into the original object from the treeList
    _.extend(this, info);
})

//now treeList contains all the corresponding info (by species) from treeInfo for each tree

Upvotes: 1

Related Questions