【问题标题】:Optional chaining for dynamic strings as property in JS动态字符串的可选链接作为 JS 中的属性
【发布时间】:2021-07-09 13:36:20
【问题描述】:

我有以下示例代码:

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

我正在尝试获取道具的值,如果这些道具存在于对象中,则类似于

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

所以对于上面的示例代码:我希望输出为 ["aaa", "bbb", "ccc"]

我知道属性的第一部分(在本例中为“输入”),第二部分将仅作为索引

是否可以使用可选链接知道这些值?我错过了什么?

【问题讨论】:

  • 请您详细说明一下。您有兴趣获取哪些值
  • 初始对象显示了不好的做法。您永远不需要像 那样构造属性。如果您需要序列中的值,请使用平面数组。
  • 实际上它们是html标签的属性,会像这样
  • 将这种模式赋予 HTML 属性也是不好的做法。
  • 如果x中的对象顺序不同,input3input1之前怎么办?

标签: javascript arrays optional-chaining


【解决方案1】:

您只需要在索引中添加一个并为不带点的对象使用括号表示法。

optional chaining operator ?. 仅适用于具有 undefined 源值。它不会切换某些程序逻辑以显示或不显示值。在这种情况下,您可以检查该属性是否存在于对象中,然后在没有一些可选链接的情况下显示想要的部分

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}`]);
});

【讨论】:

  • 同意,最好检查是否存在,谢谢!!
  • 这个只有在定义订单时才有效
  • @MandeepSingh,您使用数组。这是具有一定顺序的数据类型。我想念 s/t 吗?
  • @NinaScholz,我正在编辑订单问题,但我仍然会给你+1,因为它适用于通常情况下定义的订单
【解决方案2】:

除非您只是在寻找特定的属性,否则可选链几乎没有意义。使用Object.valuesObject.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
})

如果它只有在索引匹配时才匹配,那么它仍然不需要可选链接来读取值。

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

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

在您进行 5 次左右的编辑后,要获得您想要的输出就更奇怪了……您需要使用 reduce OR 映射和过滤器。您需要跟踪当前索引。

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);

【讨论】:

  • 可以去掉多余的index
【解决方案3】:

由于不能保证输入的顺序,我会这样做:

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);

此解决方案的一些特点:

  • 要求属性名称中的后缀介于 1 和输入数组的长度之间。
  • 允许输入数组中的某些对象没有与模式 inputXX 匹配的属性,而其他对象可能具有多个此类属性。
  • 分配给属性inputN 的值将存储在结果数组中的索引N-1 处,即使这意味着数组中会有间隙。

【讨论】:

    猜你喜欢
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多