对于以下json
[
{
"index": "xyz",
...
},
{
"index": "abc1234",
...
},
{
"index": "xyz",
...
},
{
"index": "abc5678",
...
}
...
我想分别过滤出abc值和xyz
值。
我尝试了以下内容来获取值
var x = _.filter(jsonData, function (o) {
return /abc/i.test(o.index);
});
它可以提供过滤后的输出。
现在我希望得到abc
值中最高的值,如果值为abc123
,abc444
,abc999
则代码应返回abc999
。
我可以使用lodash重新循环,但这可以在一次调用中完成 - 在过滤掉的同一个内部吗?
答案 0 :(得分:4)
您可以使用Array.prototype.reduce()
,String.prototype.replace()
与RegExp
/\D+/
匹配并删除不是数字的字符。检查字符串的前一个数字部分是否小于字符串的当前数字部分
var jsonData = [
{
"index": "xyz",
},
{
"index": "abc1234",
},
{
"index": "xyz",
},
{
"index": "abc5678",
},
{
"index": "abc1",
}];
var x = jsonData.reduce(function (o, prop) {
return /abc/i.test(prop.index)
? !o || +prop.index.replace(/\D+/, "") > +o.replace(/\D+/, "")
? prop.index
: o
: o
}, 0);
console.log(x);
答案 1 :(得分:2)
如果您想要找到最高的abc{SOME_NUMBER}
值并同时进行过滤,则可以使用常规迭代而不是_.filter
:
let jsonData = [{"index": "xyz"},{"index": "abc1234"}, {"index": "xyz"},{"index": "abc5678"}];
let max = Number.MIN_SAFE_INTEGER; // value for the max number at the end of "abc"
let item; // item containing the max abc${NUMBER} value
let filtered = []; // filtered array containing abc strings
jsonData.forEach((curr) => {
// filter test
if (/abc/i.test(curr.index)) {
filtered.push(curr);
// max value test
const [digits] = curr.index.match(/\d+/);
const test = parseInt(digits);
if (test > max) {
max = test;
item = curr;
}
}
});
console.log('Item:\n', item, '\n\n----\nFiltered:\n', filtered);
答案 2 :(得分:2)
以下是粗略且不令人满意的实施:
//filter out matching objects for possible future use
var latest = "";
var matches = _.filter(jsonData, function (o) {
var ret = /abc/i.test(o.index);
if (ret) {
var digits = o.index.replace(/\D/g,'')
if (parseInt(digits) > latest) {
latest = digits;
latestIndex = o.index
console.log(latest+">>>latestIndex")
}
return true;
}
return false;
});
console.log("latestIndex->"+latest);
}
答案 3 :(得分:2)
使用lodash执行此操作的一种方法是在代码中将filter
替换为maxBy
。
当然,这有一个缺点,即如果集合中不存在有效元素,它将随意返回一个无效元素。因此,在获得结果后,需要进行额外的有效性检查。
这就是我在单独的函数中提取验证/过滤器代码的原因:
var jsonData = [{
"index": "xyz",
}, {
"index": "abc1234",
}, {
"index": "xyz",
}, {
"index": "abc5678",
}];
var isValid = function(o) {
return /abc/i.test(o.index);
};
var highest = _.maxBy(jsonData, isValid);
if (isValid(highest)) {
console.log('The max value is: ' + highest.index);
} else {
console.log('No valid value found!');
}

<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>
&#13;
如果没有有效的元素,它的工作原理如下:
var jsonDataWithoutValidValues = [{
"index": "xyz",
}, {
"index": "xyz",
}];
var isValid = function(o) {
return /abc/i.test(o.index);
};
var highest = _.maxBy(jsonDataWithoutValidValues , isValid);
if (isValid(highest)) {
console.log('The max value is: ' + highest.index);
} else {
console.log('No valid value found!');
}
&#13;
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>
&#13;
在制作中使用这可能有点奇怪,但我觉得分享它很有趣。
答案 4 :(得分:1)
在这种情况下,你可以在过滤掉'abc'后按照你想要的方式对它进行排序
var x = _.filter(jsonData, function (o) {
return /abc/i.test(o.index);
}).sort(function (a, b) {
if(a.index > b.index) return -1;
if(a.index < b.index) return 1;
return 0;
});
如果排序正确,您可以获得最高价值,如
console.log(x[0].index)
答案 5 :(得分:1)
您可以使用Array#reduce
的单个循环并检查号码(如果存在)。
var data = [{ index: "xyz" }, { index: "abc1234" }, { index: "xyz" }, { index: "abc5678" }],
getNumber = function (s) { return s.match(/^abc(\d+)/i)[1]; },
result = data.reduce(function (r, a) {
return a.index.match(/^abc\d/i) && (!r || getNumber(r.index) < getNumber(a.index)) ? a : r;
}, undefined);
console.log(result);
答案 6 :(得分:1)
这是一种lodash链式方法:
_(data)
.map('index')
.filter(_.method('match', /abc/))
.maxBy(_.flow(_.bindKey(/\d+/, 'exec'), _.first, _.toNumber));
map()
和filter()
来电会为您提供包含abc
的叮咬列表。 maxBy()
调用找到最大值,但我们必须编写一个函数来告诉它我们想要用数字进行比较。 flow()
函数对此非常方便。在这里,我们告诉它执行正则表达式,找到结果的第一个元素,然后将其转换为数字。