Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 4

9
votes
answers
70 views
+10

为什么C和Java圆形浮点数不同?

考虑浮点数0.644696875让我们使用Java和C将其转换为八位小数的字符串:

Java
  import java.lang.Math; public class RoundExample {public static void main(String [] args){System.out.println(String.format(“%10.8f”,0.644696875)); }   

结果:0.6446968 8

自己尝试一下: http://tpcg.io/oszC0w

C
  #include&lt; stdio.h&gt; int main(){printf(“%10.8f”,0.644696875); // double to string return 0; }   < 结果:0.6446968  7   

亲自尝试: http:// tpcg .io / fQqSRF

问题

为什么最后一位数字不同?

背景

数字0.644696875不能完全表示为机器编号。它表示为分数2903456606016923/4503599627370496,其值为0.6446968749999999

这无疑是一个边缘情况。但我对这种差异的根源非常好奇。

相关: HTTPS://mathematica.stackexchange。

沙发
+60

可能这里发生的事情是他们使用稍微不同的方法将数字转换为字符串,这引入了舍入错误。在编译期间将字符串转换为浮点数的方法也可能在它们之间是不同的,由于舍入,这也可能会给出稍微不同的值。

请记住,float具有24位精度对于它的分数,它出现在~7.22十进制数[log10(2)* 24],并且它们之间的前七个数字一致,所以它只是最后几个不同的最低有效位。

欢迎来到浮点数学的有趣世界,其中2 + 2并不总是等于4。

什么是.22的十进制数字? - JL2210 6小时前

@ JL2210在浮点项中,一个非常不准确的表示将在~2.2个不同的值而不是正常值10之间徘徊,换句话说,它只有22%准确,而不是100%。 - tadman 5小时前

没有涉及浮点(32位二进制浮点)。如果有的话,该值将为0.644696891307830810546875,我们会看到“0.64469689” - 在9中结束,而不是8或7. - Eric Postpischil 4小时前

板凳
+30

结论

在这种情况下,Java规范需要麻烦的双舍入。0.6446968749999999470645661858725361526012420654296875首先转换为0.644696875然后四舍五入为0.64469688。

相比之下,C实现简单地将0.6446968749999999470645661858725361526012420654296875直接舍入到八位数,产生0.64469687。

预备

对于 Double ,Java使用IEEE-754基本64位二进制浮点。在这种格式中,最接近源文本中的数字的值0.644696875是0.6446968749999999470645661858725361526012420654296875,我相信这是用 String.format(“%10.8f”,0.644696875)格式化的实际值 1 < / p>

Java规范说的是什么

使用 Double 类型和 f 格式进行格式化的文档说:

如果精度小于 Float.toString(float) Double.toString返回的字符串中小数点后面的数字位数(分别为double),然后使用round half up算法对值进行舍入。否则,可以附加零以达到精度

让我们考虑“ Double返回的字符串。的toString(双)”。对于数字0.6446968749999999470645661858725361526012420654296875,此字符串为“0.644696875”。这是因为Java规范说 toString 只生成足够的十进制数字来唯一地区分集合中的数字。 Double ,“0.644696875”在这种情况下只有足够的数字。 2

该数字在小数点后有九位数,“%10.8f”请求八个,所以上面引用的段落说“值”四舍五入。它是什么意思 - format 的实际操作数,即0.6446968749999999470645661858725361526012420654296875,或者它提到的那个字符串,“0.644696875”?由于后者不是数值,我原以为“价值”意味着前者。但是,第二句说“否则[也就是说,如果请求更多位数]”,则可以附加“如果我们使用 format 的实际操作数,我们将显示其数字,而不是使用零。但是,如果我们将字符串作为数值,其十进制表示在其中显示的数字后将只有零。所以这似乎是解释的目的,Java实现似乎符合这一点。

因此,要使用“%10.8f”格式化此数字,我们首先将其转换为0.644696875,然后使用圆形半升规则将其舍入,产生0.64469688。

这是一个错误的规范,因为:

  • 它需要两次舍入,这会增加错误。
  • 舍入发生在难以预测和难以控制的地方。某些值将在两位小数后舍入。一些程序将在13之后进行舍入。程序无法轻易预测或调整它。

    (另外,很遗憾他们写了“可能”附加了零。为什么不“否则,”附加零 以达到精度。“使用”may“,看起来他们正在给实现选择,虽然我怀疑他们的意思是”可能“是根据是否需要零到达精度,而不是实现者是否选择附加它们。)

    脚注

    1 0.644696875 在源文本中转换为 Double ,我相信结果应该是 Double 格式中可表示的最近值。(我没有在Java文档中找到它,但它符合要求实现行为相同的Java理念,我怀疑转换是按照 Double.valueOf(String s)完成的, 确实需要这个。)最近的 Double 到0.644696875是0.6446968749999999470645661858725361526012420654296875。

    2 数字越少,七 - 数字0。64469687不足,因为最接近它的 Double 值为0.6446968 699999999774519210404832847416400909423828125 因此需要八位数来唯一地区分0.6446968 749999999470645661858725361526012420654296875

13
votes
answers
88 views
+10

为什么在将10000000转换为char时会得到38528?

Java使用32位作为焦点 - 因此最大值为65536。

但是下面的代码给出了标题中报告的结果。

  public static void main(String [] args){int a = 10000000; char b = 33; b =(char)a; 的System.out.println((int)的B); }  
    
        
up vote 10 down vote accepted favorite
沙发
+100
+50

char 是16位,而不是32位。

65535 char 的最大值,<代码> 10000000 大于此值,因此您无法将该值存储在 char 中。

10000000 in binary is 100110001001011010000000

现在当将其转换为 char 时,16位“fit”的剩余部分将被删除,留下 1001011010000000

十进制的二进制 1001011010000000 38528

非常感谢 !我现在明白为什么这段代码给了我这个结果! - Д П. 8月31日23:31

结果我期待65536。 - Д П. 8月31日23:32

我今天开始学习Java,抱歉这个愚蠢的问题:) - Д。П. 8月31日23:33

这不是一个愚蠢的问题,否则你会得到downvotes而不是upvotes。这是一个有效且易于理解的初学者的问题。假设值向下舍入而不是丢弃二进制位是有意义的。继续询问和学习,这就是我们开始的方式。 - Max Vollmer 8月31日23:35

+30

Java使用32位字符

不,Java使用 16 bit char s。

所以最大值是65536。

几乎 - 就 char 的最大值而言,它是 65535 ,但是,2s-complement 32位值的最大值为2 31 ,即 2147483647

但是下面的代码给出了标题中报告的结果。

  int a = 10000000; char b = 33; b =(char)a;    

嗯, 10000000 肯定大于 65535 ,不是吗?在尝试将该数字放入 char 时,您有何期待?你得到的是溢出

“所以最大值是65536”不,最大值是65535. - Andreas 2天前

@Andreas正确,我的疏忽。编辑。 - Fureeish 2天前

12
votes
answers
86 views
+10

JavaScript地图和查找同时:findMap?

如果不使用for循环,如何重写它?

  const a = [2,5,78,4]; const expensiveFunction = n =&gt; 2 * n; 结果; //找到第一个数字(let i = 0; i&lt; a.length; i ++){const r = expensiveFunction(a [i]); if(r> 100){result = r; 打破; console.log(result);   

我天真的方法:

  const result = a.map(expensiveFunction).find(x =&gt; x&gt; 100); 的console.log(结果);   

但是这会在所有元素上运行 expensiveFunction ,我想避免这些。在上面的例子中,我们应该避免运行 expensiveFunction(4)

有些语言有

沙发
+50
+50

内置 map 是贪婪的,所以你必须编写自己的懒人版本:

  const a = [2,5,78,4]; const expensiveFunction = n =&gt; {console.log('expensiveFunction for',n); 返回2 * n}; function * map(a,fn){for(let x of a)yield fn(x); 函数find(a,fn){for(let x of a)if(fn(x))返回x; } r = find(map(a,expensiveFunction),x =&gt; x&gt; 100)console.log('result',r)    

与stock map 不同,此 map 是一个生成器,可根据需要返回(产生)结果,而不是一次处理整个数组。此示例中的 find map 是“coroutines”并播放某种乒乓游戏,其中 find 请求结果和地图在被问到时提供它们。一旦 find 对它得到的东西感到满意,它就会退出, map 也会退出,因为没有人再要求它的结果了。

你可以还要将 map find 和朋友添加到 IteratorPrototype 使它们可用于所有迭代器并能够使用点表示法:

  const IteratorPrototype = Object.getPrototypeOf( Object.getPrototypeOf([] [Symbol.iterator]())); Object.defineProperties(IteratorPrototype,{map:{value:function *(fn){for(let x of this){yield fn(x);}},enumerable:false},find:{value:function(fn){ for(let x of this){if(fn(x))return x;}},enumerable:false},}); // const a = [2,5,78,4]; const expensiveFunction = n =&gt; {console.log('expensiveFunction',n); 返回2 * n}; 设r = a.values()。map(expensiveFunction).find(x =&gt; x&gt; 100); console.log(r)    

实际上,我非常喜欢这个想法,即基于它编写了一个完整的库: https://github.com/gebrkn/armita

我现在最喜欢的答案。 - 昨天的amaurymartiny

@amaurymartiny然后接受它... - 昨天的FZs

这里有如此多的知识,+ 1。1 - Code Maniac昨天

@FZs是的。我还在等待其他命题。 - 昨天的amaurymartiny

@CodeManiac:添加了一些解释 - 昨天乔治

+30

像这样的东西

  const a = [2,5,78,4]; const expensiveFunction = n =&gt; 2 * n; 让findMap = arr =&gt; {let found = arr.find(a =&gt; expensiveFunction(a)&gt; 100)返回发现!== undefined?expensiveFunction(found):found} console.log(findMap(a));     

提醒: - 出于好奇,但hacky或者你可以称之为误用 find

2 * n; 让findMap = arr =&gt; {let returnValue; let found = arr.find(a =&gt; {returnValue = expensiveFunction(a)return returnValue&gt; 100})return returnValue} console.log(findMap(a)); 2 * n; 让findMap = arr =&gt; {let returnValue; let found = arr.find(a =&gt; {returnValue = expensiveFunction(a)return returnValue&gt; 100})return returnValue} console.log(findMap(a));

不,最终结果应该是昂贵的功能(78),即156. - amaurymartiny昨天

@amaurymartiny再次将发现的值再次传递给昂贵的功能 - 昨天Code Maniac

昂贵的功能是昂贵的,我不想运行它两次。 - 昨天的amaurymartiny

@amaurymartiny据我所知,比你发布的代码最优化,让我想想如果我能拿出别的东西 - Code Maniac昨天

@amaurymartiny刚刚添加了一个hacky版本,你可以称之为滥用find,但仅仅是出于好奇 - 昨天Code Maniac

+20

如果您愿意接受修改数组中的第一个匹配元素,则可以执行以下操作:

  a [a.findIndex((value,index)=&gt; { value = expensiveFunction(value); return(值&gt; 100&amp;&amp;(a [index] = value))})] //返回156   

否则,你需要使用占位符变量来使其工作 - 很可能使for循环成为最干净的选项。

+10

您可以使用 .reduce ,唯一的缺点是一旦找到值就无法停止,但您不必为每个值运行 expensiveFunction 这是一个例子:

  const a = [2,5, 78,4]; const expensiveFunction = n =&gt; 2 * n; const result = a.reduce((acc,cur)=&gt; {if(!acc){const r = expensiveFunction(cur); if(r&gt; 100){acc = r;}} return acc;},null ); 的console.log(结果);  

     
			
        
+10

您可以通过使用三元运算符来简化条件并使用filter()来删除数组的布尔(null)值。

  const a = [2,5,78,100]; const result = a.map((n)=&gt; 2 * n&gt; 100?2 * n:null).filter(Boolean)[0]; console.log(result);    

     
			
        
0

为什么不使用更智能的功能进行查找?

  let desiredValue; const result = a.find(x =&gt; {desiredValue = expensiveFunction(x); return desiredValue&gt; 100;}); log(desiredValue);   

在找到第一个结果后,它会立即退出昂贵的循环。

是,但结果将是x而不是expensiveFunction(x)的返回值。 - 提图斯昨天

如果您不想再次调用昂贵的功能,请参阅更新 - vantrung -cuncon昨天

在dba.stackexchange.com上搜索它已经多次回答了。 - Sudipta Mondal 8月29日5:11

0

我遵循的方法是尽可能减少调用'expensiveFunction'函数的可能性。为此,我使用了“划分和征服算法”。您将数组分成一半,并在分割元素上调用昂贵的函数来决定继续进行哪一半。递归执行此步骤,直到找到100以上的最小元素。特别是对于非常大的数组,此方法会将昂贵的函数调用减少到显着更小的数字。因此'expensiveFunCaller'功能将在经济上称为'昂贵的功能'。该数组也应该先排序。

  const a = [2,5,78,80] .sort((a,b)=&gt; ab); const expensiveFunction = n =&gt; 2 * n; const expensiveFunCaller =([... arr])=&gt; {if(arr.length&lt; 2){let r = expensiveFunction(arr [0]); if(r> 100)返回r; 返回; } else if(arr.length === 2){let r = expensiveFunction(arr [0]); if(r> 100)返回r; r = expensiveFunction(arr [1]); if(r> 100)返回r; 返回; } let idx = Math.floor(arr.length / 2); 令r = expensiveFunction(arr [idx]); return(r&lt; 100)?expensiveFunCaller(arr.slice(idx + 1,arr.length)):expensiveFunCaller(arr.slice(0,idx + 1)); } console.log(expensiveFunCaller(a));   r = expensiveFunction(arr [1]); if(r> 100)返回r; 返回; } let idx = Math.floor(arr.length / 2); 令r = expensiveFunction(arr [idx]); return(r&lt; 100)?expensiveFunCaller(arr.slice(idx + 1,arr.length)):expensiveFunCaller(arr.slice(0,idx + 1)); } console.log(expensiveFunCaller(a));   r = expensiveFunction(arr [1]); if(r> 100)返回r; 返回; } let idx = Math.floor(arr.length / 2); 令r = expensiveFunction(arr [idx]); return(r&lt; 100)?expensiveFunCaller(arr.slice(idx + 1,arr.length)):expensiveFunCaller(arr.slice(0,idx + 1)); } console.log(expensiveFunCaller(a));  
     
			
        

不会对[2,3,78,80]起作用。预计:昂贵的功能(78)。实际:昂贵的功能(80) - 昨天的amaurymartiny

@amaurymartiny我想他想把这个函数应用于数组中最大的数字。他对78有什么特别的兴趣? - 昨天的亚的斯亚贝巴

我想找到数组中的第一个元素,其值由expensiveFunction> 100. - amaurymartiny昨天

@amaurymartiny现在非常清楚,我会尝试编辑它。 - 昨天的亚的斯亚贝巴

12
votes
answers
36 views
+10

Java流:计算基元数组中的不同值

为什么int数组的非重复计数返回的结果与Integer数组的计数结果不同?在这两种情况下我都期望得到3的结果。

  int [] numbers1 = {1,2,3}; System.out.println(“numbers1:”+ Arrays.toString(numbers1)); System.out.println(“distinct numbers1 count:”+ Stream.of(numbers1).distinct()。count()); 整数[] number2 = {1,2,3}; System.out.println(“numbers2:”+ Arrays.toString(numbers2)); System.out.println(“distinct numbers2 count:”+ Stream.of(numbers2).distinct()。count());   

结果

  numbers1:[1,2,3] distinct numbers1 count:1 numbers2:[1,2,3] distinct numbers2 count:3  
    
        
沙发
+20
+50

因为在第一个 Stream.of 方法中将整个数组视为一个元素 - 它创建一个带有数组元素的流。要使用基元数组,您必须使用 Arrays.stream

I’d use Arrays.stream to stream over an existing array in general. Then, you don’t have think about it anymore. The factory methods in the Stream class are for the varargs use case, i.e. when you use Stream.of(a), Stream.of(a, b), or Stream.of(a, b, c), etc., you also don’t need to think about the fact that there’s a specialized version for one of these calls - Holger yesterday

+60

在第一种情况下, Stream.of(numbers1)的类型是 Stream&lt; int []&gt; ,它只有一个值。

在第二种情况下, Stream.of(numbers2)的类型是 Stream&lt; Integer&gt; ,它有3个不同的值。< / p>

您使用 IntStream.of(1,2,3)来获取原始 int 的流。

+20

第一个 Stream.of 返回 Stream&lt; int []&gt; ,你有1个不同的 int [] ,名为<代码> numbers1 第二个 Stream.of 返回 Stream&lt; Integer&gt; ,你有3个不同的 Integers ,它们是 1 2 3 您可以通过将 Stream.of 替换为 Arrays.stream 来解决这个问题,以便第一次调用 Stream.of ,作为 Arrays 有一个专门的实用程序方法,它接受 int [] 并返回 IntStream

+20

Streams提供两个静态 Stream&lt; T&gt; of()方法:

  public static&lt; T&gt; 流&LT; T&GT; of(T t){..}   

  public static&lt; T&gt; 流&LT; T&GT; of(T ... values){..}   

第一种方法创建一个由单个对象组成的流,该对象作为参数提供,而第二种方法创建一个由数组元素。
在你的情况下, int [] 参数使(T values) Integer [] 时被调用参数使 of(T ... values)被调用。
预期的结果是 1 <
/ code>然后 3

为什么编译器不将两个调用绑定到()方法的

因为当传递的参数的声明类型是一个对象数组时,编译器会选择最具体的方法: of(T ... values)
但是,当传递的参数的声明类型是基元数组时,该方法不匹配: int 不是 Object
因此编译器可以选择的其余方法是(T t)

长话短说:要流式化基元数组,不要使用 Stream.of(),而是使用专门的类: IntStream.of() 或者为...设计的 DoubleStream.of()

0

  Stream.of(numbers1)  

with

  Arrays.stream(numbers1)  

int [] 正确转换为 IntStream ,而不是 Stream&lt; int []&gt;

17
votes
answers
26 views
+10

为什么Scanner类nextInt()++出现语法错误?[重复]

这个问题在这里已有答案:

  • 预期变量[重复] 4个答案 < p>尝试编译
      import java.util.Scanner; public class Main {public static void main(String [] args){Scanner in = new Scanner(System.in); int x = in.nextInt()++;   

    给出错误 java:unexpected type; 必需的:变量; 发现:

    使用 + 1 代替 ++ 解决了这个错误。

    我知道差异“将值加1”和“将值递增1”。

    但我从来没有遇到过这会产生影响的代码。有人可以解释一下吗?

up vote 10 down vote accepted favorite
沙发
+100
+50

如果你这样做:

  in.nextInt()++   

它等同于:

  in.nextInt()= in.nextInt()+ 1   

但这是不可能的。您不能将表达式的结果分配给方法调用,它必须是变量。

+60

因为 ++ 运算符通过 1 递增 int 并将新值赋给此变量,所以它不是返回任何内容的函数。您不能增加 in.nextInt(),因为它不是变量。您必须先声明一个变量才能重新分配它。

+10

当您使用 +1 时,您可以生成新值,您可以将其存储在某处或忽略,但是,当您使用 ++ 时,结果必须存储回原始变量,因此如果将此运算符应用于某个方法返回的值,则不存储用于存储结果的变量。

0

++ 运算符只适用于变量,而不适用于常量,因此编写它的方式与编写 1 ++ 之类的东西一样好,它会给你编译错误。

13
votes
answers
36 views
+10

当它是回文时,为什么这个反向的StringBuilder不等于原始的String?

我试图使用 StringBuilder reverse()检查String是否为回文结构。对于像“chan”这样没有对称性的单词,它会正确地返回 false ,但它也会返回 false 以获取像“女士”这样的真正的回文。

代码:

  StringBuilder str = new StringBuilder(“madam”); StringBuilder str2 = new StringBuilder(str); boolean res = str2.equals(str.reverse()。toString()。trim()); System.out.println(str +“”+ str2); 的System.out.println(RES);   

输出:

  madam madam false   

我正在使用Java 8运行Eclipse Neon。

up vote 10 down vote accepted favorite
沙发
+100
+50

str.reverse()。toString()。trim() String ,因此它不能等于 StringBuilder

尝试比较2 String

  boolean res = str2.toString()。equals(str.reverse()。toString ()。修剪());  
     
			
        
+20

如果你想比较字符串,你需要使用 str2.toString()

  boolean res = str2.toString()。equals(str。反向()的toString()修剪())。。  

完整解决方案:

  StringBuilder str = new StringBuilder(“madam”); StringBuilder str2 = new StringBuilder(str); boolean res = str2.toString()。equals(str.reverse()。toString()。trim()); System.out.println(str +“”+ str2); 的System.out.println(RES);   

输出:

  madam madam true   

问题是你正在比较一个StringBuilder对象带有String的str2 ,而不是比较两个字符串。此外, trim()

+10

这一行将 str2 StringBuilder 的一个实例)与 String 的实例进行比较:

  boolean res = str2.equals(str.reverse()。toString()。trim());   

两个不同类的对象总是说它们不相等是很常见的,因为它们通常不会被编程为知道如何检查不同类型对象的内容。(在某些情况下,它被指定工作,例如 java.util.List 的不同实现。)

在这种情况下,它更糟糕,因为< code> StringBuilder 不会覆盖所有 equals 方法 如果您查看课程文档,将看到 equals 列为从 Object 继承的方法之一。因此,只有在传递相同的对象实例时,它才会返回 true ; 从不比较内容

  StringBuilder sb1 = new StringBuilder(“abc”); StringBuilder sb2 = new StringBuilder(sb1); 的System.out.println(sb1.equals(SB1)); //真 相同对象System.out.println(sb1.equals(sb2)); //假 不同的对象(相同的内容)  

所以你无法比较任何 StringBuilder 这样的实例。要进行比较,将反转的结果转换回普通的 String

  String input =“madam”; input = input.trim(); String reversed = new StringBuilder(input).reverse()。toString(); System.out.println(输入+“”+反转); 的System.out.println(input.equals(反转));   

注意:如果您想要 trim()用户输入,请尽早完成。如果你在逆转后修剪,你将不得不削减比较的两半。 反向()的toString(); System.out.println(输入+“”+反转); 的System.out.println(input.equals(反转));

注意:如果您想要 trim()用户输入,请尽早完成。如果你在逆转后修剪,你将不得不削减比较的两半。 反向()的toString(); System.out.println(输入+“”+反转); 的System.out.println(input.equals(反转));

注意:如果您想要 trim()用户输入,请尽早完成。如果你在逆转后修剪,你将不得不削减比较的两半。

14
votes
answers
34 views
+10

检查是否存在对象数组

我有一个对象数组:

  items:[{name:“Cheese Puffs”,price:3},{name:“Can of Soda”,价格:1.75}] ;   

我想做像 items [“cheesePuffs”] === true 这样的事情。但是因为它在数组中它将无法正常工作。

沙发
+30
+50

您可以使用 some hasOwnProperty ,如果您需要实际值而不是布尔值,您可以使用 find 而不是 some

  const myArrOfObjects = [{cheesePuffs:”yes“},{time:”212“}]; 让findByName =(name)=&gt; {return myArrOfObjects.some(obj =&gt; {return obj.hasOwnProperty(name)})} console.log(findByName(“cheesePuffs”))console.log(findByName(“time”))console.log(findByName(“

     
			
        
+40

你想要的是 Array.find()

  myArrOfObjects.find(el =&gt; el.cheesePuffs);   

假设您正在寻找的属性是真实的,这将返回元素 {cheesePuffs:“yes”} ,这是真实的。如果找不到,则为 undefined

+20

作为建议,您也可以决定不使用数组,而是使用json对象,其中每个项目的索引是对象的唯一名称(在示例“cheesePuffs”中标识“Cheese Puffs”)< / p>

  let items = {“cheesePuffs”:{name:“Cheese Puffs”,price:3},“canOfSoda “:{名称:”Can of Soda“,价格:1.75},}; console.log(“exists:”,items.cheesePuffs!== undefined)console.log(items.cheesePuffs)//也可以这种方式访问??项目:console.log(items [“

     
			
        
+20

尝试以下代码。它将返回名称与'Cheese Puffs'匹配的对象。

  let items = [{name: “奶酪泡芙”,价格:3},{名称:“罐头苏打”,价格:1.75}]; 让itemExist = items.find(x =&gt; x.name ==='Cheese Puffs'); if(itemExist){console.log(itemExist); } else {console.log(“Item not Exist”); }    

     
			
        
+10

首先你有一个对象数组,所以你不能简单地使用

  myArrOfObjects [“cheesePuffs”]   

因为数组需要一个索引所以它应该是 myArrOfObjects [0] [“cheesePuffs”]

  let items = [{name:“Cheese Puffs”,价格:3},{name:“Can of Soda”,价格:1.75}]; let filter = items.find(el =&gt; el.price === 3); console.log(过滤器);    < / div> 

另一种方法

  let items = [{name:“Cheese Puffs”,price: 3},{name:“Can of Soda”,价格:1.75}]; let filter = items.filter(el =&gt; el.price === 3); console.log(过滤器);    

     
			
        
+10

好的简单解决方案

试试这个

  const x = [{}] ; if(x.find(el =&gt; el.cheesePuffs)== undefined)console.log(“数组中的空对象”)const myArrOfObjects = [{cheesePuffs:“yes”},{time:“212”}]; if(myArrOfObjects.find(el =&gt; el.cheesePuffs)== undefined)console.log(“数组中的空对象”)否则console.log(“数组中可用的对象”)  < / div> 

     
			
        

看看这个:docs.microsoft.com/en-us/dotnet/csharp/programming-guide/ - user743414昨天

+10

你可以使用find

  let exist = myArrOfObjects.find(o =&gt; o.cheesePuffs ==='yes') 
     
			
        

阅读行为准则:stackoverflow.com/conduct。使用代码段编写代码。 - 昨天的Dupinder Singh

即使用`并结束它使用` - Samuel Chen昨天

17
votes
answers
44 views
+10

如何将Optional 转换为Optional [暂停]

我在Java 11中有这段代码

  Object a = getObjectOrNullIfNotAvailable(); 字符串值= a == null?null:a.toString();   

我想用Optional编写这段代码,我能想到的最好的是。我没有尝试过运行它,但我怀疑它会起作用

  Optional&lt; Object&gt; oa = Optional.ofNullable(getObjectOrNullIfNotAvailable()); 可选&LT;字符串&GT; oas = oa.map(a  - &gt; a.toString()); String value = oas.orElse(null);   

除了在可选项上运行map之外,我还能做到这一点。我希望有类似下面的代码,但这不起作用

  Optional&lt; Object&gt; oa =可选。ofNullable(getObjectOrNullIfNotAvailable()); 字符串值= oa.ifPresentOrElse(a  - &gt; a.toString(),a  - &gt; null);  
    
        
up vote 10 down vote accepted favorite
沙发
+100
+50

从方法的返回值中创建一个Optional似乎有点尴尬。而是让 getObjectOrNullIfNotAvailable()方法首先返回一个Optional。然后使用 map 运算符将其转换为字符串。这是它的外观。

 可选&lt;对象&gt; oa = someOptionalReturningMethod(); String value = oa.map(Object :: toString).orElse(null);   

出于某种原因,如果您无法将方法的返回值更改为 Optional ,只需使用三元运算符保留命令解决方案即可。没错。

  String value = a == null?null:a.toString();  
     
			
        
+40

使用:

 字符串值= Optional.ofNullable(getObjectOrNullIfNotAvailable())。map(Object :: toString).orElse(null);   

否则,您可以检查Object是否为null,并在这种情况下返回String.valueOf(Object obj)或Objects.toString(Object obj)中带有“null”的String。例如。

  String value = Objects.toString(getObjectOrNullIfNotAvailable()) 
     
			
        

只是一些笔记....答案没有错 - 卡洛斯赫伯格8月30日17:51

如果方法返回null,这将失败。使用Optional.ofNullable()代替 - knittl 8月30日18:58

+30

您可以使用 map ,然后使用 orElse ,不需要将它们分开:

  String value = Optional.ofNullable(a ).map(Object :: toString).orElse(null);  
     
			
        

我认为你的意思是Optional.ofNullable。谢谢,这是有效的 - abhaybhatia 8月30日17:23

@abhaybhatia抱歉在你的情况下它应该是Nullable否则你会得到NullPointerException - YCF_L 8月30日17:27

18
votes
answers
50 views
+10

如何将月份值从一个Date对象复制到另一个Date对象?[重复]

这个问题在这里已有答案:

  • Date.getMonth()方法有错误吗? 9个答案

    给定两个Date对象,如何正确设置第一个对象的月份到另一个对象的月份?

    我正面临着一个任务将日期,月份和年份从一个Date对象复制到另一个Date对象。复制日期和年份按预期工作,当我试图复制月份时问题就出现了。 < p>使用 b.setMonth(a.getMonth())会导致b的月份过多。

    使用 b.setMonth(a.getMonth() - 1)但是,导致b的第一个月比需要的少。

    以下打字代码:

     < code> let a = new Date(2018,1,12); 设b = new Date(); 的console.log(a)的 的console.log(b)中; 的console.log( '===='); 的console.log(a.getMonth()); 的console.log(b.getMonth()); b.setMonth(a.getMonth()); 的console.log( '===='); 的console.log(a.getMonth()); 的console.log(b.getMonth()); b.setMonth(a.getMonth() -  1); 的console.log( '===='); 的console.log(a.getMonth()); 的console.log(B。得到月());   

    返回:

      2018年2月12日星期一00:00:00 GMT + 0100 2019年8月29日星期四16:11:03 GMT + 0200 === = 1 7 ==== 1 2 ==== 1 0 // 2  -  1 = 0?  

    看似2 - 1应该给1 (a.getMonth() - 1),但显然Date对象的行为不同。在javascript / typescript中将月份从一个Date对象复制到另一个对象的正确方法是什么?我想将两个日期转换为字符串,复制正确的字符并将字符串解析回Date会起作用,但我想知道是否有更简单,更清晰的方法。 03 GMT + 0200 ==== 1 7 ==== 1 2 ==== 1 0 // 2 - 1 = 0?

    看似2 - 1应该给1 (a.getMonth() - 1),但显然Date对象的行为不同。在javascript / typescript中将月份从一个Date对象复制到另一个对象的正确方法是什么?我想将两个日期转换为字符串,复制正确的字符并将字符串解析回Date会起作用,但我想知道是否有更简单,更清晰的方法。 03 GMT + 0200 ==== 1 7 ==== 1 2 ==== 1 0 // 2 - 1 = 0?

    看似2 - 1应该给1 (a.getMonth() - 1),但显然Date对象的行为不同。在javascript / typescript中将月份从一个Date对象复制到另一个对象的正确方法是什么?我想将两个日期转换为字符串,复制正确的字符并将字符串解析回Date会起作用,但我想知道是否有更简单,更清晰的方法。

沙发
+90
+50

问题是 setMonth()方法有一个可选的第二个参数,即日期( DOCS )。如果您没有提供当天的价值,它将自动使用其中一个日期。

因此,您的A日期是2018年2月12日,而您的B日期是2019年8月29日。

通过 b.setMonth(a.getMonth()); ,你隐含地说 b.setMonth(1,29); (1是a.getMonth( )29是b日期的日期。

所以你试图将日期设定为2月29日,这在2019年是不可能的,它将月份改为1到3月(第2个月) )。

+70

这是因为这是你的幸运(或不幸!)日。这是你工作的特定日期。

今年2月只有28天。当您将“2019年8月29日”的月份设置为2月时,您将尝试创建无效日期“2019年2月29日”。这可以概括为“2019年3月1日”。

如果你昨天尝试过这个实验,你就不会看到这个问题。

+20

这是每月的天数问题。

当你这样做时:

  b.setMonth(a.getMonth());   

你得到的是b日期,但是以2月为月份:2019年2月29日星期四16:11:03 GMT + 0200

2019年2月没有29天。所以日期实际上是3月1日:2019年3月1日星期四16:11:03 GMT + 0200

这就是为什么你在第二组控制台日志中获得第2个月的原因。

最后你设定b.month不是一个月,所以它从一个日期(从二月到一月)减去一个月。

0

因为您使用a.getMonth()而不是b.getMonth()。所以你的主要月份是1而不是2。

0

在设置月份时,您还需要指定可以使用此代码的日期

  var a =新日期(2018年,1日,12日); var b = new Date(); 的console.log(a)的 的console.log(b)中; 的console.log( '===='); 的console.log(a.getMonth()); 的console.log(b.getMonth()); b.setMonth(a.getMonth(),1); 的console.log( '===='); 的console.log(a.getMonth()); 的console.log(b.getMonth()); b.setMonth(a.getMonth() -  1,1); 的console.log( '===='); 的console.log(a.getMonth());

     
			
        
20
votes
answers
34 views
+10

JavaScript用*替换前5个字符

我需要Javascript Regex来替换前5个字符。以下是一些例子。第一行是输入,第二行是预期输出。你能告诉我如何实现这个目标吗?

我试过了。但是如果输入小于4,它们都不起作用。

 。{5}到*****和^ d {5}到*****   

示例

  123456789 XXXXX6789 123 XXX 123456 XXXXX6 1 X 12345 XXXXX  
    
        
沙发
+40

你的第一个正则表达式需要一点调整,这应该有效。

  let reg = /.{1,5}/ let string ='123456789'; let string2 ='123'; console.log(string.replace(reg,(m)=&gt;“X”.repeat(m.length))); console.log(string2.replace(reg,(m)=&gt;“X”.repeat(m.length)));    

     
			
        
板凳
+40

您可以在 .replace()中使用回调函数或lambda:

 < code> var arr = ['123456789','123','123456','1','12345']; arr.forEach(el =&gt; console.log(el,'::',el.replace(/ ^ d {1,5} /,m =&gt; m.replace(/ d / g,'X') )))   

     
			
        
地板
+30

如果你不是在寻找正则表达式解决方案,那么你也可以尝试这个选项。基于substring()方法的替代方法

  function replace_String(string,numberofchar,chartoreplace){return string.substring(0,numberofchar).split(”“)。map(ele =&gt; ele = chartoreplace).join(”“ ).concat(string.substring(numberofchar,string.length))} console.log(replace_String(“123456789”,5,“X”))console.log(replace_String(“1”,1,“*”))   

     
			
        
4楼
+30

你可以做很多方法。一个是两个替换语句

  const hideFive = str =&gt; str.replace(/ ^ d {1,5} /,x =&gt; x.replace(/./ g,'*'))var tests = [“1”,“12”,“123”,“1234 “,”12345“,”123456“,”1234567“,”12345678“,”1234567890“] tests.forEach(val =&gt; console.log(val,'=',hideFive(val)))    

没有胖箭

<

5楼
+30

你可以替换第一个字符并取出字符串的切片。

  const replaceFirst5 = s =&GT; '*'。repeat(Math.min(5,s.length))+ s.slice(5); 的console.log(replaceFirst5( “123456789”)); console.log(replaceFirst5(“123”));    

     
			
        
6楼
+30

您可以使用 replace repeat

  ^。{1,5}   
  • ^ - 字符串开头
  • 。{1,5} - 匹配除新行以外的任何内容,最少一次,最多5次< / li>

      let replaceFirst5 =(str)=&gt; {return str.replace(/ ^。{ 1,5} /,m =&gt;“X”.repeat(m.length))} console.log(replaceFirst5(“123456789”))控制台。log(replaceFirst5(“123”))   
    
         
    			
            

    它使用解构将部分返回值分配给现有标识符主体和客户。 - jonrsharpe 8月28日9:25

    @jonrsharpe可能值得指出,只有客户被破坏.. - Keith 8月28日9:34

7楼
0

假设这些数字包含在名为“数字”的类中

jQuery代码

  $。each('。numbers' ,function(){let num = $(this).text(); var j =“”; for(let i = 0; i&lt; num.length; i ++){if(i == 5){break;} j + =“*”;} var res = str.replace(num.substring(0,5),j); document.getElementById(“demo”)。innerHTML = res;});