现代JavaScript中的条件连接

现代JavaScript中的条件连接,javascript,Javascript,我正在寻找一种有条件地连接字符串的简洁方法 见: const something=response.data .map(i=>{ const id=i.附件?[0]?.id 返回{image:id?/servlet/servlet.FileDownload?file=“+id:undefined,…i} }) 我很想把这个内联起来,但找不到办法。使用诸如('something'+foo')之类的空协同编码运算??未定义的永远不会解析为未定义 编辑:我想将其最小化为.map(I=>({image

我正在寻找一种有条件地连接字符串的简洁方法

见:

const something=response.data
.map(i=>{
const id=i.附件?[0]?.id
返回{image:id?/servlet/servlet.FileDownload?file=“+id:undefined,…i}
})
我很想把这个内联起来,但找不到办法。使用诸如
('something'+foo')之类的空协同编码运算??未定义的
永远不会解析为未定义


编辑:我想将其最小化为
.map(I=>({image:/servlet/servlet.FileDownload?file=“+I.Attachments?[0]?.Id,…I}))
但如果没有Id,则
图像
为空。我希望在某个地方有一个巧妙的技巧。

这就是你想要的吗

const something = response.data
  .map(i => ({ 
     image: i.Attachments?.[0]?.Id && "/servlet/servlet.FileDownload?file=" + i.Attachments?.[0]?.Id,          
     ...i 
     })
  );

你可以过一辈子,但我们会变傻的。或者,只需另一个
贴图
层即可实现以下功能:

const urlPrefix = "/servlet/servlet.FileDownload?file=";

const something = response.data
    .map(i => ({ id: i.Attachments?.[0]?.Id, i }) )
    .map(t => ({ image: t.id ? (urlPrefix + t.id) : undefined, ...t.i }) );
当今大多数编程语言的难点之一是无法或难以表达条件字符串格式化操作(我想知道这是否是语言设计者阻止我们使用字符串的阴谋,毕竟,字符串很昂贵,而且在没有GC的情况下需要管理PITA)。但由于这是JavaScript,所以始终存在核心选项:扩展
String.prototype

String.prototype.p = a => this ? (a+this) : undefined;
这意味着您的代码可以保留其原始形式,但可以转换为:

const something = response.data
  .map(i => {
    return { image: (i.Attachments?.[0]?.Id||'').p("/servlet/servlet.FileDownload?file="), ...i }
  })
然后又缩短为:

const something = response.data
  .map(i => ({image: (i.Attachments?.[0]?.Id||'').p("/servlet/servlet.FileDownload?file="), ...i }))

更新:现在我已经睡过了,下面是生活版:

const something = response.data
  .map(i => ({image: (s=>s?("/servlet/servlet.FileDownload?file="+s):undefined)(i.Attachments?.[0]?.Id), ...i }))
为了好运再次收缩:

const something = response.data.map(i=>({image:(s=>s?("/servlet/servlet.FileDownload?file="+s):void 0)(i.Attachments?.[0]?.Id),...i}))

总共135个字符。

我想我知道你在找什么了。您希望能够内联重用复杂表达式,而无需将表达式样式的箭头函数转换为语句样式的箭头函数。 在这些情况下,可以使用表达式赋值

const answer = (x=complex_expression?.[0]?.Id, x && "long/string.With/stuff"+x);
下面是一个例子:

const something = response.data.map(i => ({
  image: (id=i.Attachments?.[0]?.Id, id && "/servlet/servlet.FileDownload?file=" + id),
  ...i,
}));
如果不希望图像键为
null
,可以执行以下操作:

const something = response.data.map(i => ({
  ...(id=i.Attachments?.[0]?.Id, id && { image: "/servlet/servlet.FileDownload?file=" + id}),
  ...i,
}));

data
i
的数据类型和典型值是什么?您是在使用Promises、Observables/RxJS还是其他东西?因为可能有一堆不必要的代码,所以很难说出您在问什么。你是不是刚买了一个可能更短版本的
id?“/servlet/servlet.FileDownload?file=“+id:undefined
”具有多个属性的对象您当前的代码看起来非常合理me@CertainPerformance谢谢CodeGolf是否更适合论坛?这将导致定义
image
属性,但当
i.Attachments?[0]?.Id
为空时,该属性的值为空;而我对OP的理解是,如果为空/null,则应省略
image
属性。仅供参考,这比OP长29个字符code@Dai否,OP将
未定义
作为
图像
的回退值。除非
i.Attachments?[0]
有一个
Id
属性是错误的,但不是
未定义的
,否则此代码将产生相同的结果
i.Attachments?[0]?.Id
可能是一个昂贵的操作(想象一下
[].find()
),所以我只想执行一次。@dzh为什么会“昂贵”?这只是一个解引用链。如果传递的对象具有非平凡的属性getter,这将非常昂贵,如果这些只是来自JSON的DTO,这是非常不可能的(如果不是不可能的话)。Yep也有这个想法,但IMO解决方案更快、更容易实现understand@dzh关于绩效,你的“意见”无关紧要,重要的是实际的基准测试:)如果您能为我们提供基准测试所需的原始数据,我很乐意分析我的答案。@Dai我想OP指的是他们的O(n)解决方案和您的2O(n)解决方案。实时性的差异可能是可以忽略的,毫无疑问,这在实践中并不重要。可读性将因此我的观点仍然成立:)@Phil
2O(n)
不是正确的表示法-连续使用
map
两次并不一定会导致两次天真的迭代。在现代JS引擎中有很多疯狂但有效的优化(来源:我曾经在Chakra上工作)“没有将表达式风格的箭头函数转换为语句风格的箭头函数”-我没有从OP的帖子中推断出这一点