简体   繁体   中英

Destruct a string from split to named object

I am investigating how create a named object in one go, using destruct

A search for javascript destruct* split object did not reveal how to directly destruct a string into an object using split.

I do not mean reduce or map but pure destructing

const list = { ..... } = `......`.split(..)

or at least

const rowItem = { ..... } = `......`.split(..)

My initial version works, but there should be a neater way with less steps

The initial split on lines is fine. It is the filling of the list using destruct I am curious about

 const rows = `100|Description 1|a| 101|Description 2|a| 102|Description 3|b|`.split("\\n") let list = {} rows.forEach(row => { const [ProductId, Description, subCat, ] = row.split("|") list[ProductId] = {"Description": Description, "subCat": subCat } }) console.log(list) 

You can do something like this with IIFE

 const rows = `100|Description 1|a| 101|Description 2|a| 102|Description 3|b|`.split("\\n") let list = {} rows.forEach(row => { (([ProductId, Description, subCat]) => (list[ProductId] = { Description, subCat }))(row.split("|")) }) console.log(list) 

You can consider using Object.fromEntries if it's available in your environment

 const rows = Object.fromEntries(`100|Description 1|a| 101|Description 2|a| 102|Description 3|b|` .split("\\n") .map(row => row.split('|')) .map(([key, Description, subCat]) => [key, { Description, subCat }]) ); console.log(rows); 

It is possible to set the property to an existing object while destructuring.

 const row = { Description: 'Description 1', subCat: 'a' }, o = { }; // existing object to be updated; ({ Description: o.Description, subCat: o.subCat } = row); console.log(o) 

In your case, you have dynamic id keys, nested property updates and you are destructuring an array instead of an object. It becomes complex, but it is possible to apply the above logic to your code (This is extremely hackish and purely academic. This should never ever be used in an actual code base)

 const str = "100|Description 1|a|", splits = str.split('|'), list = {};// existing object ({ 0: id, [-1]: list[id]= {}, 1: list[id].Description, 2: list[id].subCat } = splits) console.log(list) 

This destructures the array like an object. It gets the property with key 0 and sets it to the id variable. Then destructure the -1 property. This is non-existent, so the default value is used and list[id] = {} is set.

This is how the transpiled code looks like:

var _str$split = str.split('|');

id = _str$split[0];
list[id] = _str$split[-1] === undefined ? {} : _str$split[-1];
list[id].Description = _str$split[1];
list[id].subCat = _str$split[2];
console.log(list);

Applying this to your original snippet:

 const rows = `100|Description 1|a| 101|Description 2|a| 102|Description 3|b|` let list = {}, id; rows.split("\\n") .forEach(str => ({ 0: id, [-1]: list[id] = {}, 1: list[id].Description, 2: list[id].subCat } = str.split('|')) ) console.log(list) 


Another option is to use matchAll and Object.fromEntries()

 const str = `100|Description 1|a| 101|Description 2|a| 102|Description 3|b|`; const regex = /(\\d+)\\|([^|]+)\\|(\\w+)/g; const output = Object.fromEntries( Array.from( str.matchAll(regex), ([, id, Description, subCat]) => [id, { Description, subCat }] ) ) console.log(output) 

matchAll is still in Draft stage but it is implemented except by IE and Safari. You can easily polyfill it . It is basically looping through exec results

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM