根据值从对象数组中选择一个属性: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"] 

因为这两个values 有checked: true

我已经尝试根据检查值过滤掉:

let result = arr.filter(item => item.checked);

我正在获取具有设置为 truechecked 属性值的对象。

我们将不胜感激。

【问题讨论】:

您输入的语法无效。考虑提供一个有效的数据结构。数组没有键值对,只有值 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】:

您基本上可以同时使用.reducemapfilter。下面我使用[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的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript - 根据属性值从数组中取出对象

根据特定值从数组中选择项目

通过属性值从对象数组中获取JavaScript对象[重复]

通过属性值从对象数组中获取JavaScript对象[重复]

按属性值从数组中删除项目

Pyspark:如何根据另一列中的匹配值从数组中的第一次出现中选择直到最后的值