根据最大后续零值删除逗号后的零

时间:2018-02-01 11:34:51

标签: javascript string loops nested-loops

我有一个带有网格的页面,用户的号码会被保存。它有以下模式 - 每个数字以逗号后的3位数结尾。当用户输入

时,它看起来不太好看
123,450
123,670
123,890

逗号之后只有2个数字要好得多,因为上一个0绝对毫无意义且多余。

只有当数组中至少有一个元素不以0

结尾时,它仍然应该有3个数字的方式

例如:

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..
    }   
})

在我的实现中,我不知道该怎么做,因为我必须遍历每个元素,但如果至少有一个数字的最后一个数字等于零,那么就打破它。为了做到这一点,我必须打破外循环,但不知道如何,我绝对相信我没有......

5 个答案:

答案 0 :(得分:2)

我认为以下代码正是您正在寻找的内容,请操纵数字并查看更改:

&#13;
&#13;
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));
});
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这个解决方案可能看起来有点麻烦但它应该适用于所有可能的场景。它应该很容易使总是返回最小数量的小数位/前导零。

我希望它有所帮助。

&#13;
&#13;
// 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))
&#13;
&#13;
&#13;

答案 2 :(得分:1)

According to MDN

  

除了抛出异常之外,没有办法停止或中断forEach()循环。如果您需要这样的行为,forEach()方法是错误的工具。请使用普通循环或for...of

如果您将forEach循环转换为for循环,则可以使用标签和break语句将其展开:

&#13;
&#13;
// 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);
&#13;
&#13;
&#13;

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

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

所有在一起:

&#13;
&#13;
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']));
&#13;
&#13;
&#13;

答案 3 :(得分: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.11 3.1423 3.1

最大长度为: 4 (1423)

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

我们在3.11中添加2个零,即3.1100

答案 4 :(得分: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);
    }
}