如何在 html table 列中找到最低值

How to find lowest value inside html table column

我有这个 html table 使用数据动态创建的 tables jquery 插件...

所以我有:

<tbody>
   <tr role="row" class="odd">
      <td class="sorting_1">2015-09-29 15:33:09</td>
      <td>1230</td>
      <td></td>
      <td></td>
      <td>All inclusive</td>
   </tr>
   <tr role="row" class="even">
      <td class="sorting_1">2015-09-29 16:01:03</td>
      <td>1309</td>
      <td></td>
      <td></td>
      <td>nma</td>
   </tr>
   <tr role="row" class="odd">
      <td class="sorting_1">2015-09-29 16:01:03</td>
      <td>1900</td>
      <td></td>
      <td></td>
      <td>nema</td>
   </tr>
   <tr role="row" class="even">
      <td class="sorting_1">2015-09-29 16:08:17</td>
      <td>2000</td>
      <td></td>
      <td></td>
      <td>nema poruka za sada</td>
   </tr>
   <tr role="row" class="odd">
      <td class="sorting_1">2015-09-29 16:32:54</td>
      <td>3900</td>
      <td></td>
      <td></td>
      <td>to je to</td>
   </tr>
   <tr role="row" class="even">
      <td class="sorting_1">2015-09-29 16:32:57</td>
      <td>1200</td>
      <td></td>
      <td></td>
      <td>+magacin</td>
   </tr>
   <tr role="row" class="odd">
      <td class="sorting_1">2015-09-29 17:43:58</td>
      <td>3400</td>
      <td>2015-09-29</td>
      <td>2015-09-30</td>
      <td>+skladiste + niza cena + tacan da tum utovara</td>
   </tr>
</tbody>

如何从第二列中找到最低值?

更新:

我现在看到最好从 JSON 中找到最低值... 所以这是我的 JSON:

{"data":[{"vreme":"2015-09-29 15:33:09","cena":1230,"utovar":"","istovar":"","poruka":"All inclusive"},{"vreme":"2015-09-29 16:01:03","cena":1309,"utovar":"","istovar":"","poruka":"nma"},{"vreme":"2015-09-29 16:01:03","cena":1900,"utovar":"","istovar":"","poruka":"nema"},{"vreme":"2015-09-29 16:08:17","cena":2000,"utovar":"","istovar":"","poruka":"nema poruka za sada"},{"vreme":"2015-09-29 16:32:54","cena":3900,"utovar":"","istovar":"","poruka":"to je to"},{"vreme":"2015-09-29 16:32:57","cena":1200,"utovar":"","istovar":"","poruka":"+magacin"},{"vreme":"2015-09-29 17:43:58","cena":3400,"utovar":"2015-09-29","istovar":"2015-09-30","poruka":"+skladiste + niza cena + tacan da tum utovara"}]}

如何找到 data.cena 的最低值?

首先,我建议更新您的代码片段以提高可读性。它可能会鼓励更多人回答。

其次,jQuery 方法:您可以遍历 table 行,在每行中获取第二个 td,并将​​值存储在数组中。然后您可以跟踪数组以获取最低值。

var values = [];
var lowestVal = 0;

$('tr').each(function(){
    var value = $(this).children('td').eq(1).html();
    lowestVal = value;
    values.push(value);
});


for(var x = 0; x < values.length; x++){
    if(values[x] < lowestVal)lowestVal  = values[x];
}

console.log(lowestVal);

编辑

啊,我看到你已经更新了你的片段。谢谢:)

Edit2:已更新以修复错误。已测试。

我建议使用 :nth-of-type(2) 到 select 每个 <tr>

中的第二个 <td> 元素

$('tr td:nth-of-type(2)') 应该获取第二个 <td> 元素。

$('tr td:nth-of-type(2)').text() 将 return 文本值,因此,1230、1309 等

使用 $.map() and .sort() 如下。

var lowest = $("tr td").map(function() {
    //When it's the 2nd td in every row
    if ( $(this).index() === 1 ) {
        return $(this).text();
    }
}).get().sort(function(a, b) {
    return a - b;
}).shift(); //get the first item out

A Demo

编辑:

对于您发布的JSON,您可以像上面一样做,稍作修改,如下所示。

var lowest = $.map(json.data, function(node) {
    return node.cena;
}).sort(function(a, b) {
    return a - b;
}).shift(); //get the first item out

Another Demo

编辑:

还有一个简单的方法:

var lowest = Infinity; //The value Infinity (positive infinity) is greater than any other number;
json.data.forEach(function(node) {
    lowest = node.cena < lowest && node.cena || lowest;
});

Another Demo

您可以使用以下脚本:

var values = [];
$('table tr td:nth-child(2)').each(function () {
    var value = parseFloat($(this).text());
    values.push(value);
});
console.log(Math.min.apply(Math,values));

首先,让我们将您的 tbody 包裹在 table 中,以使一切顺利进行。之后您可以使用此代码来获得您要查找的结果。

首先定义一个 min 函数,您可以在代码中需要整数 min 功能的任何地方使用它。然后我们只遍历所有第二列条目并将它们作为整数值存储在数组中。

最后,我们在数组中找到最小值,在本例中将其显示在控制台中。

Array.prototype.min = function () {
  return Math.min.apply(Math, this);
};

var colVals = [];

$('tbody tr td:nth-child(2)').each(function () {
  colVals.push(parseInt($(this).text()));
});


console.log(colVals.min());

JSFIDDLE

编辑

对于 JSON 你可以这样做

Array.prototype.min = function () {
  return Math.min.apply(Math, this);
};

var values = [];

for(var i = 0; i < response['data'].length; i++){
  values.push(response['data'][i].cena);
}

console.log(values.min());

JSFIDDLE JSON

为了回答你的第一个问题,"how do I get the lowest value from a table column?" 我将提供以下功能作为一种方法,尽管我已经扩展它以识别和 return <td> 元素最小值、最大值和最接近平均值的值:

// creating a named function, with an 'opts' argument
// to allow for user-customisation:
function valuesInColumn(opts) {

    // these are the 'default' settings of the function,
    // allowing the user to avoid having to set options
    // in the event that the default matches the requirements:

    // columnIndex: Number or numeric String, specifying the
    //              CSS (1-based) index of the column to work
    //              with (defaults to 1, the first <td> element
    //              of its parent <tr>).
    // table:       HTMLTableElement node, upon which the function
    //              should operate (defaults to the first <table>
    //              element in the document).

    var settings = {
        'columnIndex': 1,
            'table': document.querySelector('table')
    };

    // iterating over the properties of the opts argument:
    for (var property in opts) {

        // if the opts Object has a defined property (not
        // inherited from its prototype chain) and the
        // specified property-value is not undefined):
        if (opts.hasOwnProperty(property) && 'undefined' !== opts[property]) {
            // we update the property of the default settings
            // Object to the property-value of the user-defined
            // property-value of the opts Object:
            settings[property] = opts[property];
        }
    }

    // ensuring that the settings.columnIndex is a Number:
    n = parseInt(settings.columnIndex, 10);

    // getting a (non-live) NodeList using querySelectorAll to
    // all <td> elements that are the specific nth-child of their
    // parent <tr> which is itself a child of the <tbody> element
    // within the supplied HTMLTableElement:
    var columnCells = settings.table.querySelectorAll('tbody > tr > td:nth-child(' + n + ')'),

     // converting the above NodeList into an Array, using
     // Function.prototype.call() to use the Array method,
     // Array.prototype.slice(), on the supplied NodeList:
        columnValues = Array.prototype.slice.call(columnCells, 0),

     // defining the values to return:
        values = {

            // using Array.prototype.reduce() to reduce the array
            // of cells to the cell containing the maximum value:
            'max': columnValues.reduce(function (v, c) {
                // v: the previously-found-value
                // c: the current array-element over which we're
                // iterating with Array.prototype.reduce().

                // here we use parseInt() to assess whether the
                // number in the cell's text ('c.textContent')
                // is greater than that of the previously-found
                // cell or not; if it is we return the current
                // cell (c) if not we return the previously-found
                // cell (v) using a conditional operator:
                return parseInt(c.textContent, 10) > parseInt(v.textContent, 10) ? c : v;
            }),
                'min': columnValues.reduce(function (v, c) {

                // exactly as above, but here we're testing that
                // the numeric textContent-value is less than
                // that of the previously-found cell:
                return parseInt(c.textContent, 10) < parseInt(v.textContent, 10) ? c : v;
            }),
                'sum': columnValues.reduce(function (v, c) {

                // here we're finding the sum of all the text-values,
                // so we simply add the numeric textContent value
                // of the current Array-element ('c') to the value
                // represented by the previously-found value ('v'):
                return parseInt(v, 10) + parseInt(c.textContent, 10);

            // here we initialise the reduce method's previous-value
            // to 0 in order to guard against accidental 'NaN':
            }, 0),

                // here we again find the sum (as above) but then
                // divide by the length of the Array to find the
                // mean value:
                'meanValue': columnValues.reduce(function (v, c) {
                return parseInt(v, 10) + parseInt(c.textContent, 10);
            }, 0) / columnValues.length
        };

    // iterating over each of the <td> elements in the Array:
    columnValues.forEach(function (c) {

        // setting its 'data-meanDelta' attribute value to the
        // difference between its own text-value and that of the
        // discovered meanValue:
        c.dataset.meanDelta = values.meanValue - parseInt(c.textContent, 10);
    });

    // using Math.prototype.reduce() again, to find the <td>
    // element with the nearest text-value to the found
    // meanValue:
    var firstMeanCell = columnValues.reduce(function (v, c) {

        // here we use parseInt() to convert the
        // dataset.meanDelta property-value of the Node (v)
        // into a decimal Number, and then finding its absolute
        // value (using Math.abs(), so "-10" is coverted first
        // to -10 and then to 10); doing the same to the
        // property-value of the current element(c) and
        // and retaining whichever of the two is the least:
        return Math.abs(parseInt(v.dataset.meanDelta, 10)) < Math.abs(parseInt(c.dataset.meanDelta, 10)) ? v : c;
    }),

        // because it's quite possible for multiple <td> to have
        // the same value it's quite possible that the mean
        // value will be held in multiple cells; so here
        // we filter the array of <td> elements using
        // Array.prototype.filter():
        nearestMeans = columnValues.filter(function (c) {

            // again we get the absolute-value of the
            // dataset.meanDelta property-value of the
            // current Array-element (c) and check if it's
            // equal to that of the firstMeanCell; if it
            // is equal we retain that array element,
            // otherwise it's simply discarded:
            if (Math.abs(parseInt(c.dataset.meanDelta, 10)) === Math.abs(parseInt(firstMeanCell.dataset.meanDelta, 10))) {
                return c;
            }
        });

    // setting the additional properties of the values
    // Object:
    values.means = nearestMeans;
    values.minValue = parseInt(values.min.textContent, 10);
    values.maxValue = parseInt(values.max.textContent, 10);

    // returning the values object to the calling context:
    return values;
}

// setting the columnIndex to 2 (because we want the second
// column and CSS is 1-based, unlike the 0-based JavaScript,
// and caching the returned Object in the 'extremes' variable:
var extremes = valuesInColumn({
    'columnIndex': 2
});

// adding the 'minimum' class-name to the element held
// in the extremes.min property:
extremes.min.classList.add('minimum');

// adding the 'maximum' class-name to the element held
// in the extremes.max property:
extremes.max.classList.add('maximum');

// adding the 'mean' class-name to the first element held
// in the extremes.means property (which is an Array):
extremes.means[0].classList.add('mean');

// logging the other values to the console (in the attached
// demo these are instead logged into the Snippet itself, 
// courtesy of a script from T.J. Crowder - see the HTML
// comments for attribution):
console.log(extremes.sum, extremes.minValue, extremes.maxValue, extremes.meanValue);

function valuesInColumn(opts) {
    var settings = {
        'columnIndex': 1,
            'table': document.querySelector('table')
    };

    for (var property in opts) {
        if (opts.hasOwnProperty(property) && 'undefined' !== opts[property]) {
            settings[property] = opts[property];
        }
    }

    n = parseInt(settings.columnIndex, 10);

    var columnCells = settings.table.querySelectorAll('tbody > tr > td:nth-child(' + n + ')'),
        columnValues = Array.prototype.slice.call(columnCells, 0),
        values = {
            'max': columnValues.reduce(function (v, c) {
                return parseInt(c.textContent, 10) > parseInt(v.textContent, 10) ? c : v;
            }),
                'min': columnValues.reduce(function (v, c) {
                return parseInt(c.textContent, 10) < parseInt(v.textContent, 10) ? c : v;
            }),
                'sum': columnValues.reduce(function (v, c) {
                return parseInt(v, 10) + parseInt(c.textContent, 10);
            }, 0),
                'meanValue': columnValues.reduce(function (v, c) {
                return parseInt(v, 10) + parseInt(c.textContent, 10);
            }, 0) / columnValues.length
        };

    columnValues.forEach(function (c) {
        c.dataset.meanDelta = values.meanValue - parseInt(c.textContent, 10);
    });
    var firstMeanCell = columnValues.reduce(function (v, c) {
        return parseInt(Math.abs(v.dataset.meanDelta), 10) < parseInt(Math.abs(c.dataset.meanDelta), 10) ? v : c;
    }),
        nearestMeans = columnValues.filter(function (c) {
            if (Math.abs(parseInt(c.dataset.meanDelta, 10)) === Math.abs(parseInt(firstMeanCell.dataset.meanDelta, 10))) {
                return c;
            }
        });

    values.means = nearestMeans;
    values.minValue = parseInt(values.min.textContent, 10);
    values.maxValue = parseInt(values.max.textContent, 10);

    return values;
}

var extremes = valuesInColumn({
    'columnIndex': 2
});

extremes.min.classList.add('minimum');
extremes.max.classList.add('maximum');
extremes.means[0].classList.add('mean');

// Note that in the real - not on SO - world, console.log() would be used much
// more simply, here we use T.J. Crowder's offered 'snippet.log()' approach, 
// as shown in the HTML comments:

var output = ['min', 'max', 'mean'];

output.forEach(function (v) {
  snippet.log(v + ': ' + extremes[v + 'Value']);
});
.maximum {
  background-color: red;
}
.minimum {
  background-color: limegreen;
}
.mean {
  background-color: aqua;
}

/*
    purely to move the 'snippet.log' output away from the actual HTML content
*/
body p:first-of-type::before {
  content: '';
  display: block;
  width: 100%;
  height: 1em;
  border-bottom: 2px solid #000;
  margin-bottom: 0.5em;
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

<table>
  <tbody>
    <tr role="row" class="odd">
      <td class="sorting_1">2015-09-29 15:33:09</td>
      <td>1230</td>
      <td></td>
      <td></td>
      <td>All inclusive</td>
    </tr>
    <tr role="row" class="even">
      <td class="sorting_1">2015-09-29 16:01:03</td>
      <td>1309</td>
      <td></td>
      <td></td>
      <td>nma</td>
    </tr>
    <tr role="row" class="odd">
      <td class="sorting_1">2015-09-29 16:01:03</td>
      <td>1900</td>
      <td></td>
      <td></td>
      <td>nema</td>
    </tr>
    <tr role="row" class="even">
      <td class="sorting_1">2015-09-29 16:08:17</td>
      <td>2000</td>
      <td></td>
      <td></td>
      <td>nema poruka za sada</td>
    </tr>
    <tr role="row" class="odd">
      <td class="sorting_1">2015-09-29 16:32:54</td>
      <td>3900</td>
      <td></td>
      <td></td>
      <td>to je to</td>
    </tr>
    <tr role="row" class="even">
      <td class="sorting_1">2015-09-29 16:32:57</td>
      <td>1200</td>
      <td></td>
      <td></td>
      <td>+magacin</td>
    </tr>
    <tr role="row" class="odd">
      <td class="sorting_1">2015-09-29 17:43:58</td>
      <td>3400</td>
      <td>2015-09-29</td>
      <td>2015-09-30</td>
      <td>+skladiste + niza cena + tacan da tum utovara</td>
    </tr>
  </tbody>
</table>

外部 JS Fiddle demo,对于 experimentation/development。

参考文献: