根据值从对象数组中选择一个属性:Javascript
Posted
技术标签:
【中文标题】根据值从对象数组中选择一个属性:Javascript【英文标题】:Select a property from an array of objects based on a value : Javascript 【发布时间】:2019-12-03 12:25:01 【问题描述】:我有一个具有以下结构的对象数组:
var arr = [
"value": "abc",
"checked": true
,
"value": "xyz",
"checked": false
,
"value": "lmn",
"checked": true
];
let result = arr.filter(item => item.checked);
console.log(result);
我希望输出是:
["abc", "lmn"]
因为这两个value
s 有checked: true
。
我已经尝试根据检查值过滤掉:
let result = arr.filter(item => item.checked);
我正在获取具有设置为 true
的 checked
属性值的对象。
我们将不胜感激。
【问题讨论】:
您输入的语法无效。考虑提供一个有效的数据结构。数组没有键值对,只有值 use filter to return property values in an object的可能重复 【参考方案1】:您可以使用reduce
并检查checked
属性是否为真,然后push
(正如assoron 所指出的)累加器的值 - 不需要2个循环:
const arr = [
"value": "abc", "checked": true ,
"value": "xyz", "checked": false ,
"value": "lmn", "checked": true
]
const filtered = arr.reduce((a, o) => (o.checked && a.push(o.value), a), [])
console.log(filtered)
【讨论】:
@assoron 是的,你是对的。我只写了 concat ,所以你可以把它写在一行上,以便更具可读性。而且传播语法非常慢,我记得曾经写过一个 JSPerf,而 iirc 慢了 50%。 @assoron 检查这个性能 jsperf.com/push-vs-concat-with-reduce/1 - 慢 94% 大声笑 我古老的浏览器设置让 concat 慢了 40%。 你可以在一行中使用push
:(a.push(o.value), a)
。
是的 - 逗号运算符评估所有传递的代码,然后使用最后一个。所以a.push(o.value)
运行,然后a
作为表达式的返回值,从函数中返回。有意义吗?【参考方案2】:
var a = [];
arr.forEach( (i)=> i.checked ? a.push(i.value) :null )
它将评估在 foreach 中为数组的每个元素传递的方法,并检查 element.checked 是否为真,它会将 element.value 推送到数组 a 中,这是所需的输出。
【讨论】:
【参考方案3】:您基本上可以同时使用.reduce
和map
和filter
。下面我使用[v].slice(+!c)
构建了一个累积数组,如果c
为真,它将将该值添加到(累积)数组中,否则它不会将它添加到数组中(因为[v].slice(+!false)
将返回[]
,和[...[]]
将给[]
):
const arr = [
"value": "abc",
"checked": true
,
"value": "xyz",
"checked": false
,
"value": "lmn",
"checked": true
];
const res = arr.reduce((a, value:v, checked:c) => [...a, ...[v].slice(+!c)], []);
console.log(res);
【讨论】:
【参考方案4】:Array.prototype.reduce()
可能会对您有所帮助。 reduce()
回调有两个参数,第一个参数是旧的/先前的迭代值,第二个参数是当前的迭代值/元素。
因此,使用此函数,我们可以将当前迭代值保持为之前的迭代值(总值)。
reduce() 方法对数组的每个元素执行(您提供的)reducer 函数,从而产生单个输出值。
var arr = ["value": "abc","checked": true,"value": "xyz","checked": false,"value": "lmn","checked": true]
const result = arr.reduce((acc, cur) => ((cur.checked && acc.push(cur.value)), acc), [])
console.log(result)
【讨论】:
只返回最后一个(...)【参考方案5】:您没有推送新数组中的值。试试这个它工作正常。
const arr = [ "value": "abc", "checked": true , "value": "xyz", "checked": false , "value": "lmn", "checked": true ]
let result = []
let check = arr.filter((val) =>
if (val.checked)
result.push(val.value)
)
console.log(result);
【讨论】:
【参考方案6】:创建一个泛型函数,您只需在其中传递键值和数组,它将过滤掉基本参数的数组
var arr = [
"value": "abc",
"checked": true
,
"value": "xyz",
"checked": false
,
"value": "lmn",
"checked": true
]
function filterList(keyValue, list)
let filteredList = [];
for(let i = 0; i < list.length; i++)
if(list[i]["checked"] === keyValue)
filteredList.push(list[i]["value"]);
return filteredList;
console.log(filterList(true, arr));
【讨论】:
【参考方案7】:这里的所有解决方案都是有效的,但是如果您更喜欢使用 ES6+ 语法的更迭代的方法,您可以显式地对您的项目进行每个循环,以便让您的读者非常清楚您的意图(另外,它比连接 @987654321 更快@ 和 map
,因为它会在您的列表中循环两次):
const items = [
"value": "abc",
"checked": true
,
"value": "xyz",
"checked": false
,
"value": "lmn",
"checked": true
];
const formattedListOfFilteredItems = [];
for (item of items)
if (item.checked)
formattedListOfFilteredItems.push(item.value);
console.log(formattedListOfFilteredItems);
【讨论】:
【参考方案8】:不要把事情复杂化。只需使用普通的 for 循环并保存运行时。即使您的数组中的所有元素都有一个选中的属性true
,以下内容也只会迭代一次数组。
var arr = [
"value": "abc",
"checked": true
,
"value": "xyz",
"checked": false
,
"value": "lmn",
"checked": true
];
var results = [];
for(var i=0; i<arr.length-1; i++)
if(arr[i].checked === true)
results.push(arr[i].value)
如果您查看 .map
/.filter
的内部实现,他们将使用 while 循环迭代数组。假设您有一个数据,其中所有元素都设置为选中为 true,那么 filter 将遍历所有元素,然后 map 将遍历它们以从中获取值。
【讨论】:
这就是我使用 reduce 的原因 :) 尽管如此,for 循环在这里更有效。 @Kobe 同意...!【参考方案9】:使用map和filter函数如下:
var arr = [
"value": "abc",
"checked": true
,
"value": "xyz",
"checked": false
,
"value": "lmn",
"checked": true
]
let checkedValues = arr.map((item) => item.checked ? item.value : null).filter(item => item);
console.log(checkedValues);
【讨论】:
【参考方案10】:使用过滤器和地图:
const arr =["value":"abc","checked":true,"value":"xyz","checked":false,"value":"lmn","checked":true];
const result = arr.filter(res=>res.checked).map(ele=>ele.value);
console.log(result);
【讨论】:
如果你想要唯一的值: const result = Array.from(new Set(arr.filter(res=>res.checked).map(ele=>ele.value)));跨度> 【参考方案11】:修复数据结构并使用过滤器和映射
var obj = [
"value" : "abc",
"checked" : true
,
"value" : "xyz",
"checked" : false
,
"value" : "lmn",
"checked" : true
]
console.log(obj.filter(function(e)return e.checked==true).map(function(e)return e.value))
【讨论】:
你怎么在这里使用旧语法?当它不是 es6 时,它在一行上看起来很奇怪:P【参考方案12】:首先,这不是有效的 JS - 你需要交换你的括号和大括号。数组使用[]
,对象使用,而不是相反。
其次,你应该先filter
根据checked
属性取出想要的对象,然后使用map
提取你想要的属性:
const arr =["value":"abc","checked":true,"value":"xyz","checked":false,"value":"lmn","checked":true];
const res = arr.filter(( checked ) => checked).map(( value ) => value);
console.log(res);
【讨论】:
以上是关于根据值从对象数组中选择一个属性:Javascript的主要内容,如果未能解决你的问题,请参考以下文章