Ruby-如何对数组进行切片并根据条件求和

时间:2019-06-05 12:41:59

标签: arrays ruby algorithm

我找不到实现以下目标的方法:

  • 给出了一个整数数组
  • 第二个数字乘以
  • 对所有整数求和

我尝试使用Enumerble#each_slice,但仍然不知道如何在修改后的数组切片部分上调用Array#sum

input =  [6, 8, 2, 4, 4, 4, 5, 5, 0]
input.each_slice(2) {|slice| p slice }
#=> 
[6, 8]
[2, 4]
[4, 4]
[5, 5]
[0]

现在,我想将每对中的每个最后一个元素相乘(在相乘之前可以应用condition

[6, 8] => 8 *2
[2, 4] => 4 *2
[4, 4] => 4 *2
[5, 5] => 5 *2
[0]

并将初始数组的所有数字与第二个数字相乘后相加:

[6, 16, 2, 8, 4, 8, 5, 10, 0].sum

有什么主意吗? 谢谢。

6 个答案:

答案 0 :(得分:2)

这是一种精确做到这一点的方法,“每隔一个元素相乘然后求和”

input =  [6, 8, 2, 4, 4, 4, 5, 5, 0]

input.map.with_index{|elem, idx| idx.odd? ? elem * 2 : elem} # => [6, 16, 2, 8, 4, 8, 5, 10, 0]
     .sum # => 59

对此略有变化,不使用索引(可能使评论者满意)

input.zip([false, true].cycle).
      map {|elem, is_second| is_second ? elem * 2 : elem}.
      sum

答案 1 :(得分:2)

还有另一个使用Enumerable#each_sliceEnumerable#sum的选项,它需要一个块:

input.each_slice(2).sum { |a, b| a + 2* (b || 0) }

答案 2 :(得分:1)

要添加其他选项:

input
  .zip([1, 2].cycle)
  .map { |a| a.inject(:*) }
  .sum

答案 3 :(得分:1)

我来到的解决方案是@iGian的改进版本:

digits = [6, 8, 2, 4, 4, 4, 5, 5, 0]
digits.each_slice(2).sum { |first, last=0| first + my_custom_function(last) }

def my_custom_function(digit)
  digit *= 2
  digit -= 9 if digit > 9
  digit
end

希望这会有所帮助。

答案 4 :(得分:0)

    <TechnicalProfile Id="ResourceOwnerPasswordCredentials-OAUTH2">
      <DisplayName>Local Account SignIn</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <Metadata>
        <Item Key="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account</Item>
        <Item Key="UserMessageIfInvalidPassword">Your password is incorrect</Item>
        <Item Key="UserMessageIfOldPasswordUsed">Looks like you used an old password</Item>
        <Item Key="DiscoverMetadataByTokenIssuer">true</Item>
        <Item Key="ValidTokenIssuerPrefixes">https://sts.windows.net/</Item>
        <Item Key="METADATA">https://login.microsoftonline.com/{AzureADB2C-Tenant-Name}.onmicrosoft.com/.well-known/openid-configuration</Item>
        <Item Key="authorization_endpoint">https://login.microsoftonline.com/{AzureADB2C-Tenant-Name}.onmicrosoft.com/oauth2/token</Item>
        <Item Key="response_types">id_token</Item>
        <Item Key="response_mode">query</Item>
        <Item Key="scope">email openid</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="logonIdentifier" PartnerClaimType="username" Required="true" DefaultValue="{OIDC:Username}"/>
        <InputClaim ClaimTypeReferenceId="password" Required="true" DefaultValue="{OIDC:Password}" />
        <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" />
        <InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" />
        <InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
        <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="{Proxy-Identity-Experience-Framework-ClientId}" />
        <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="{Identity-Experience-Framework-ClientId}" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" />
        <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" />
      </OutputClaimsTransformations>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>

我更喜欢@Sergio Tulentsev的答案,这个答案可能不会使用索引,但还会产生副作用。

我想知道的是,是否有一种方法可以给map()一个布尔值?我用其他语言看过类似的东西。

答案 5 :(得分:0)

只是为了好玩,坚持each_slice

input.each_slice(2).map { |s| s[1] ? [s[0], s[1] * 2] : s[0] }.flatten

# => [6, 16, 2, 8, 4, 8, 5, 10, 0] 

input.each_slice(2).map { |s| s[1] ? [s[0], s[1] * 2] : s[0] }.flatten.sum
# => 59