]> git.ardis.lu - csvio/commitdiff
Add `CSVNormalizer.toObject()` method
authorArdis Lu <ardisglu@gmail.com>
Sun, 5 Oct 2025 05:51:22 +0000 (22:51 -0700)
committerArdis Lu <ardisglu@gmail.com>
Sun, 5 Oct 2025 05:51:22 +0000 (22:51 -0700)
examples/README.md
examples/data/ex4_3-in.csv [new file with mode: 0644]
examples/data/ex4_3-out.csv [new file with mode: 0644]
examples/ex4_3.js [new file with mode: 0644]
src/normalization.js
test/normalization.test.js

index 4238659a0e100113c17427184d356bdf14bc9e45..047d2ee5925ef6fa7b9289826fef67f2c49538e0 100644 (file)
@@ -57,3 +57,5 @@ These examples demonstrate the extended API.
 [Example 4.1: Using `CSVNormalizer` and `CSVDenormalizer`](./ex4_1.js) ([input](./data/ex4_1-in.csv), [output](./data/ex4_1-out.csv))
 
 [Example 4.2: Using `CSVNormalizer` and `CSVDenormalizer` with `CSVTransformer`](./ex4_2.js) ([input](./data/ex4_2-in.csv), [output](./data/ex4_2-out.csv))
+
+[Example 4.3: Using `CSVNormalizer.toObject()`](./ex4_3.js) ([input](./data/ex4_3-in.csv), [output](./data/ex4_3-out.csv))
diff --git a/examples/data/ex4_3-in.csv b/examples/data/ex4_3-in.csv
new file mode 100644 (file)
index 0000000..5f22363
--- /dev/null
@@ -0,0 +1,4 @@
+a,b,c,🏴‍☠️,😂\r
+111,222,333,444,555\r
+111,222,333,444,555\r
+111,222,333,444,555\r
diff --git a/examples/data/ex4_3-out.csv b/examples/data/ex4_3-out.csv
new file mode 100644 (file)
index 0000000..1e06ef7
--- /dev/null
@@ -0,0 +1,4 @@
+a,b,c,🏴‍☠️,😂\r
+intercepted: 111,intercepted: 222,intercepted: 333,intercepted: 444,intercepted: 555\r
+intercepted: 111,intercepted: 222,intercepted: 333,intercepted: 444,intercepted: 555\r
+intercepted: 111,intercepted: 222,intercepted: 333,intercepted: 444,intercepted: 555\r
diff --git a/examples/ex4_3.js b/examples/ex4_3.js
new file mode 100644 (file)
index 0000000..61f3975
--- /dev/null
@@ -0,0 +1,42 @@
+// ## Example 4.3: Using `CSVNormalizer.toObject()`
+// 
+// Use the static method `CSVNormalizer.toObject()` if you just want to read the values of `CSVNormalizerField`.
+// For more advanced usage, such as keeping the underlying `row` object in sync with changes to the value, see
+// `CSVNormalizer.toFieldMap()`.
+
+import { CSVReader, CSVWriter, CSVNormalizer, CSVDenormalizer, CSVTransformer } from '../src/index.js';
+/** @import { CSVNormalizerHeader, CSVNormalizerField } from '../src/index.js'; */
+
+/** @type {Array<CSVNormalizerHeader>} */
+const headers = [
+  { name: 'a' },
+  { name: 'b' },
+  { name: 'c' },
+  { name: '🏴‍☠️' },
+  { name: '😂' }
+];
+
+/**
+ * @param {Array<CSVNormalizerField>} row 
+ * @returns {Array<CSVNormalizerField>}
+ */
+function transform(row) {
+  const obj = CSVNormalizer.toObject(row);
+  const { a, b, c } = obj; // Destructuring works
+  const pirate = obj['🏴‍☠️']; // Access by field name works
+  const laughing = obj['😂'];
+  const out = [ // Manually construct a new output row
+    { name: 'a', value: `intercepted: ${a}` },
+    { name: 'b', value: `intercepted: ${b}` },
+    { name: 'c', value: `intercepted: ${c}` },
+    { name: '🏴‍☠️', value: `intercepted: ${pirate}` },
+    { name: '😂', value: `intercepted: ${laughing}` },
+  ];
+  return out;
+}
+
+await new CSVReader(new URL('./data/ex4_3-in.csv', import.meta.url))
+  .pipeThrough(new CSVNormalizer(headers))
+  .pipeThrough(new CSVTransformer(transform))
+  .pipeThrough(new CSVDenormalizer())
+  .pipeTo(new CSVWriter(new URL('./data/ex4_3-out.csv', import.meta.url)));
index e9d7683ee36c687ca144c51cbb4f533d6ee39cbb..9312c04bd6aa1ff3adcea0e1d23eedfc8cb5e05f 100644 (file)
@@ -309,6 +309,22 @@ export class CSVNormalizer extends TransformStream {
     console.warn(`Could not fix date: "${original}". Passing through as a string.`);
     return original;
   }
+
+  /**
+   * Create a simple object that maps each `CSVNormalizerField` `name` to its `value`. Useful if you just want to read all the
+   * values in a normalized CSV row.
+   * 
+   * The `displayName` and `emptyField` values of a field are lost in the resulting object.
+   * @param {Array<CSVNormalizerField>} row A normalized CSV row.
+   * @returns {Record<string,any>} An object where each key is a field `name` and the value is the field's `value`.
+   */
+  static toObject(row) {
+    const object = {};
+    for (const field of row) {
+      object[field.name] = field.value;
+    }
+    return object;
+  }
 }
 
 /**
index df5b9d4b1bdecb5e3f14210ba00f86647da119e9..4c25b9c6ed01a6e330c79b51db52a92346601b80 100644 (file)
@@ -181,6 +181,34 @@ suite('CSVNormalizer.fixExcelDate', { concurrency: true }, () => {
   }
 });
 
+suite('CSVNormalizer.toObject', { concurrency: true }, () => {
+  test('converts simple fields', { concurrency: true }, async () => {
+    const row = [
+      { name: 'a', value: 1 },
+      { name: 'b', value: 2 },
+      { name: 'c', value: 3 }
+    ];
+    const obj = CSVNormalizer.toObject(row);
+    deepStrictEqual(obj.a, 1);
+    deepStrictEqual(obj.b, 2);
+    deepStrictEqual(obj.c, 3);
+  });
+  test('converts complex field names', { concurrency: true }, async () => {
+    const row = [
+      { name: '🏴‍☠️', value: 1 }
+    ];
+    const obj = CSVNormalizer.toObject(row);
+    deepStrictEqual(obj['🏴‍☠️'], 1);
+  });
+  test('converts complex field values', { concurrency: true }, async () => {
+    const row = [
+      { name: 'a', value: { 'b': [1n] } }
+    ];
+    const obj = CSVNormalizer.toObject(row);
+    deepStrictEqual(obj.a.b[0], 1n);
+  });
+});
+
 suite('CSVNormalizer', { concurrency: true }, () => {
   test('can remove extra columns in CSV', { concurrency: true }, async () => {
     await createCSVMockStream([
This page took 0.045891 seconds and 4 git commands to generate.