基于连续零的最大值,去除逗号后面的零

4

我有一个带有网格的页面,用户的数字会被保存在里面。它有以下模式 - 每个数字以逗号后的3个数字结束。例如,当用户输入为:

123,450
123,670
123,890

最好只保留小数点后两位数字,因为末尾的0是毫无意义且多余的。

只有在至少一个数组元素不以0结尾时,才应该保留三位数字。

例如:

123,455
123,450
123,560

在这种情况下,数组的第一个元素的最后一位数字不等于0,因此所有元素都应该有3个数字。2个或1个零也是同样的情况。
零是多余的:
123,30
123,40
123,50

零是必要的:

123,35
123,40
123,50

问题是如何以编程方式实现它?我已经开始了这样的工作:
var zeros2Remove = 0;
numInArray.forEach(function(item, index, numInArray) 
{
    var threeDigitsAfterComma = item.substring(item.indexOf(',') + 1);

    for(var j = 2; j <= 0; j--) 
    {
        if(threeDigitsAfterComma[j] == 0) 
        {
            zeros2Remove =+ 1;
        } 
        else //have no idea what to do..
    }   
})

在我的实现中,我不知道该如何做,因为我必须遍历每个元素,但如果至少有一个数字的最后一位等于零,就要中断它。为了做到这一点,我必须中断外部循环,但不知道如何做到,我绝对确定我不必......


如果所有的字符串都是形如“123,000”的格式,会发生什么? - AuxTaco
小数点后只有一个零。 - Robert Baratheon
5个回答

2
我认为下面的代码正是您所需要的,请操作数字并查看更改:

我认为下面的代码正是您所需要的,请操作数字并查看更改:

var arr = ["111.3030", "2232.0022", "3.001000", "4","558.0200","55.00003000000"];
var map = arr.map(function(a) {
  if (a % 1 === 0) {
    var res = "1";
  } else {
    var lastNumman = a.toString().split('').pop();
    if (lastNumman == 0) {
      var m = parseFloat(a);
      var res = (m + "").split(".")[1].length;
    } else {
      var m = a.split(".")[1].length;
      var res = m;
    }
  }

  return res;

})
var maxNum = map.reduce(function(a, b) {
  return Math.max(a, b);
});

arr.forEach(function(el) {
  console.log(Number.parseFloat(el).toFixed(maxNum));
});


非常感谢,您的代码解决了问题!但是,您是否可以详细解释一下这个解决方案并分解这段代码呢?我想自己掌握它。谢谢 :) - Robert Baratheon

1

根据MDN的说法,

除非抛出异常,否则无法停止或中断forEach()循环。如果需要这样的行为,则forEach()方法是错误的工具。请改用普通循环或for...of

如果将您的forEach循环转换为for循环,则可以通过标签和break语句中断它:

// unrelated example
let i;
let j;
outerLoop:
for (i = 2; i < 100; ++i) {
  innerLoop:
  for (j = 2; j < 100; ++j) {
    // brute-force prime factorization
    if (i * j === 2183) { break outerLoop; }
  }
}
console.log(i, j);

我给你举了一个无关的例子,因为你的问题根本不需要嵌套循环。你可以使用正则表达式在字符串中找到尾随零的数量:

function getTrailingZeroes (str) {
  return str.match(/0{0,2}$/)[0].length;
}

str.match(/0{0,2}$/)会在str的结尾找到0到2个零,并将它们作为一个字符串放入一个含有一个元素的数组中返回。该字符串的长度是你可以从str中删除的字符数。你可以对数字字符串数组进行一次遍历,在必要时进行分离,并使用Array.map作为一个单独的截断循环:

function getShortenedNumbers (numInArray) {
  let zeroesToRemove = Infinity;
  for (const str of numInArray) {
    let candidate = getTrailingZeroes(str);
    zeroesToRemove = Math.min(zeroesToRemove, candidate);
    if (zeroesToRemove === 0) break;
  }

  return numInArray.map(str => str.substring(0, str.length - zeroesToRemove);
}

全部在一起:

function getTrailingZeroes (str) {
  return str.match(/0{0,2}$/)[0].length;
}

function getShortenedNumbers (numInArray) {
  let zeroesToRemove = Infinity;
  for (const str of numInArray) {
    let candidate = getTrailingZeroes(str);
    zeroesToRemove = Math.min(zeroesToRemove, candidate);
    if (zeroesToRemove === 0) break;
  }

  return numInArray.map(str => str.substring(0, str.length - zeroesToRemove));
}

console.log(getShortenedNumbers(['123,450', '123,670', '123,890']));
console.log(getShortenedNumbers(['123,455', '123,450', '123,560']));


1

试试这个

function removeZeros(group) {
    var maxLength = 0;
  var newGroup = [];
    for(var x in group) {
    var str = group[x].toString().split('.')[1];
    if(str.length > maxLength) maxLength = str.length;
  }

  for(var y in group) {
    var str = group[y].toString();
    var substr = str.split('.')[1];
    if(substr.length < maxLength) {
        for(var i = 0; i < (maxLength - substr.length); i++) 
        str += '0';
    } 
    newGroup.push(str); 
  }

  return newGroup;
}

在jsfiddle上尝试:https://jsfiddle.net/32sdvzn1/1/

我的脚本检查每个数字的小数部分的长度,要记住JavaScript会删除十进制数中的最后一个零,所以3.10将变成3.1,所以当有数字以零结尾时,长度会减少,在这种情况下,我们只需将零添加到数字。

更新

我已经更新了脚本,新版本将添加与分析数字的小数位长度之间的差异相同的零。

示例

我们有:3.113.14233.1

最大长度为:4(1423)

maxLenght(4)- .11的长度(2)= 2

我们将2个零添加到3.11,它将变成3.1100


1
这个解决方案可能看起来有点繁琐,但它应该适用于所有可能的情况。它应该很容易地始终返回最少数量的小数位数/前导零。
我希望它能有所帮助。

// Define any array
const firstArray = [
  '123,4350',
  '123,64470',
  '123,8112390',
]

const oneOfOfYourArrays = [
  '123,30',
  '123,40',
  '123,50',
]

// Converts 123,45 to 123.45
function stringNumberToFloat(stringNumber) {
  return parseFloat(stringNumber.replace(',', '.'))
}

// For 123.45 you get 2
function getNumberOfDecimals(number) {
  return number.split('.')[1].length;
}

// This is a hacky way how to remove traling zeros
function removeTralingZeros(stringNumber) {
  return stringNumberToFloat(stringNumber).toString()
}

// Sorts numbers in array by number of their decimals
function byNumberOfValidDecimals(a, b) {
  const decimalsA = getNumberOfDecimals(a)
  const decimalsB = getNumberOfDecimals(b)
  return decimalsB - decimalsA
}

// THIS IS THE FINAL SOLUTION
function normalizeDecimalPlaces(targetArray) {
  const processedArray = targetArray
  .map(removeTralingZeros) // We want to remove trailing zeros
  .sort(byNumberOfValidDecimals) // Sort from highest to lowest by number of valid decimals

  const maxNumberOfDecimals = processedArray[0].split('.')[1].length

  return targetArray.map((stringNumber) => stringNumberToFloat(stringNumber).toFixed(maxNumberOfDecimals))
}

console.log('normalizedFirstArray', normalizeDecimalPlaces(firstArray))

console.log('normalizedOneOfOfYourArrays', normalizeDecimalPlaces(oneOfOfYourArrays))


0

我认为你可以先假设要去掉两个额外的零,然后循环遍历数组,寻找最后两位的数字。考虑到逗号,我假设你的numArray元素都是字符串,并且长度相同。

var numArray = ['123,000', '456,100', '789,110'];

var removeTwo = true, removeOne = true;
for (var i = 0; i < numArray.length; i++) {
    if (numArray[i][6] !== '0') { removeTwo = false; removeOne = false; }
    if (numArray[i][5] !== '0') { removeTwo = false; }
}

// now loop to do the actual removal
for (var i = 0; i < numArray.length; i++) {
    if (removeTwo) {
        numArray[i] = numArray[i].substr(0, 5);
    } else if (removeOne) {
        numArray[i] = numArray[i].substr(0, 6);
    }
}

它们并不相同。它们都以相同的长度(3)结尾。这就是为什么我用 item.substring(item.indexOf(',') + 1); 进行了分割的原因。 - Robert Baratheon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接