简体   繁体   中英

Optional chaining for dynamic strings as property in JS

I have following sample code:

var x = [
{input1: "aaa"},
{input2: "bbb"},
{input444: "ddd"},
{input55: "eee"}
{input3: "ccc"},
]

I am trying to get values of props which if exists in the object something like

x.forEach((item, index) => {
 console.log(item.[`input${index}`]);
})

So for above sample code: I want output to be ["aaa", "bbb", "ccc"]

I know the first part of the property (which in this example is 'input') and second part will be index only

Is it possible to know the values using Optional chaining? What I am missing?

You need just to add one to index and take bracket notation for the object without dot.

The optional chaining operator ?. works only for having undefined source value. It does not switch some program logic for either showing a value or not. In this case, you could check if the property exists in the object and then show th wanted part without some optional chaining

 var x = [{ input1: "aaa" }, { input2: "bbb" }, { input3: "ccc" }, { input444: "ddd" }, { input55: "eee" }]; x.forEach((item, index) => { if (`input${index + 1}` in item) console.log(item[`input${index + 1}`]); });

Optional chaining makes little sense unless you are only looking for a specific property. Use Object.values or Object.entries .

 var x = [ {input1: "aaa"}, {input2: "bbb"}, {input3: "ccc"}, {input4: "ddd"}, {input5: "eee"} ] x.forEach((item, index) => { console.log(Object.values(item)); console.log(Object.values(item)[0]); // If it is just one, reference it })

If it has to match only if the index matches than it still does not require optional chaining to read the value.

 var x = [ {input1: "aaa"}, {input2: "bbb"}, {input3: "ccc"}, {input4: "ddd"}, {input555: "eee"} ] x.forEach((item, index) => { console.log(item[`input${index+1}`]); })

And after your 5th or so edit, to get the output you want is even weirder.... You would need to use reduce OR map and filter. You need to keep track of the current index.

 const x = [ {input1: "aaa"}, {input2: "bbb"}, {input444: "ddd"}, {input55: "eee"}, {input3: "ccc"}, ]; let current = 1; const out = x.reduce(function (acc, obj) { const key = `input${current}`; if(obj.hasOwnProperty(key)){ acc.push(obj[key]); current++; } return acc; }, []); console.log(out);

Since the order of the input is not guaranteed, I would do this:

 var x = [{input1: "aaa"}, {input2: "bbb"},{input444: "ddd"},{input55: "eee"},{input3: "ccc"},]; let result = Object.assign([], ...x.flatMap(o => Object.entries(o).filter(([k]) => k.startsWith('input') && +k.slice(5) >= 1 && +k.slice(5) <= x.length ).map(([k, v]) => ({ [k.slice(5)-1]: v }) ) )); console.log(result);

Some characteristics of this solution:

  • Requires that the suffix in the property name lies between 1 and the length of the input array.
  • Allows that some objects in the input array have no properties that match the pattern inputXX , while others may have multiple such properties.
  • A value that is assigned to a property inputN will be stored at index N-1 in the resulting array, even if that means there will be gaps in the array.

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