2

It would be great to have a .csv file reader that can take a 'key' as an input to the reader to create an associative array.

I am reading a .csv file that looks something like this (simplified):

State,ID,Population
Alabama,AL,1234
California,CA,5678
Hawaii,HI,90123
North Dakota,ND,45678
etc...

And I would like to use a .csv file reader to allow me to do something like this:

csv_to_associatve_array("file.csv", function(foo,'ID') {

    // Where ID is foo's "key" using the ID column of the csv file 

    // Then access foo as an associative array something like this:

    console.log(foo['ND'].State)
});

This should log 'North Dakota' to the console.

I've searched quite a bit and can't seem to find anything. Maybe I'm using the wrong keywords.

In any case, if you have a neat way to access csv data using a key, that would be spiffy. Else, if no alternative, do you know a way to create an associative array from a 'normal' js array that a noob can understand and access as array[ID].State?

altocumulus
  • 21,179
  • 13
  • 61
  • 84
AZBlue
  • 105
  • 7
  • May be duplicate of https://stackoverflow.com/questions/7431268/how-to-read-data-from-csv-file-using-javascript – brk Apr 18 '18 at 05:05
  • you mean `Object`, right? while requesting third party libraries is off topic, I'll say one word `papaparse` – Jaromanda X Apr 18 '18 at 05:12
  • JS doesn't have associative arrays. Objects are more or less unsuitable for the purpose, since the order is not kept. – Teemu Apr 18 '18 at 05:15
  • @Teemu Hmmm...I thought accessing array['ID'].property was associative? As opposed to array[integer].property ... [JavaScript Data Structures - The Associative Array](http://www.i-programmer.info/programming/javascript/1441-javascript-data-structures-the-associative-array.html) – AZBlue Apr 18 '18 at 06:12
  • Well, it is called object in JS, though dot notation is usually used to access object properties. The problem in storing a file, line by line, into an object is, that the order of the object properties is not defined, and the lines might get disordered when reading. Probably you should just use an array. – Teemu Apr 18 '18 at 06:20
  • I believe Mike Bostock uses the associative array concept in the following example: [US State Map] (http://bl.ocks.org/NPashaP/a74faf20b492ad377312) ... in which he sets sampleData[d]=... ...where 'd' is a key of state IDs (abbreviations). The beautiful thing about the uStates.draw() function is that after receiving an "associative" array, Bostock does not care about order. He uses his OWN set of keys (locally defined state IDs) to access the passed associative array. In this case, it does not matter where or how js is storing the data (In My Humble Opinion :) ). – AZBlue Apr 18 '18 at 06:54
  • Well, if you don't mind about the order, then you can use objects. But if you're going to add/edit the lines and then save the file, or the order is otherwise important, then you'd better go with arrays. See also [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map). – Teemu Apr 18 '18 at 07:01

1 Answers1

3

You can use d3.map() which creates a map, i.e. a key-value mapping, which is essentially what you are looking for. The neat advantage of using a d3.map over using JavaScript's built-in Map type introduced by ES6 is the fact that you can provide a key function to be used to extract the value for the key (ID in your case). The creation of the map becomes as simple as

const states = d3.map(data, d => d.ID);

You can then access an individual value, i.e. a state, by using states.get(key).

Have a look at the following snippet demonstrating the usage:

// Setup for loading of local csv data. Not relevant for answer. 
const csv = URL.createObjectURL(new Blob([
`State,ID,Population
Alabama,AL,1234
California,CA,5678
Hawaii,HI,90123
North Dakota,ND,45678`
]));
// End of setup.

d3.csv(csv)
  .then(data => {
    const states = d3.map(data, d => d.ID); // Converts the parsed CSV data to a map.
    console.log(states.get("ND").State);    // > North Dakota
  });
<script src="https://d3js.org/d3.v5.js"></script>
altocumulus
  • 21,179
  • 13
  • 61
  • 84
  • 2
    As we normally use `d3.map()` with key/value pairs it's common forgetting that you can pass an array of objects to be the values. That's very nice. – Gerardo Furtado Apr 18 '18 at 08:52