对象数组的对象。获取具有相同属性的所有值的长度
Posted
技术标签:
【中文标题】对象数组的对象。获取具有相同属性的所有值的长度【英文标题】:Object of array of objects. Get the length of all values with the same property 【发布时间】:2019-06-05 15:59:08 【问题描述】:我有一个看起来像这样的对象:
var obj =
"array1": [
"label": "something1",
"ref": "option2a"
,
"label": "something2",
"ref": "option2b"
,
"label": "something3",
"ref": "option2a"
,
"label": "something4",
"ref": "option2a"
,
"label": "something5",
"ref": "option2a"
],
"array2": [
"label": "something6 is the longest label",
"ref": "option3a"
,
"label": "Other",
"ref": "option3b"
]
我想得到最长标签的长度。在这种情况下,我想返回 17。因为最长的标签是“somethinglongest”,长度为 17。
【问题讨论】:
到目前为止你有什么尝试?somethinglongest
的长度只有16...
好问题。使用 map() 和 ...
(tripple dot notaion) 来解构数组非常棒。
【参考方案1】:
直截了当的方法:
let obj =
"array1": [
"label": "something1", "ref": "option2a",
"label": "something2", "ref": "option2b",
"label": "something3", "ref": "option2a",
"label": "something4", "ref": "option2a",
"label": "something5", "ref": "option2a"
],
"array2": [
"label": "something6 is the longest label", "ref": "option3a",
"label": "Other", "ref": "option3b"
]
;
let longest = 0
for (key in obj)
if (!obj.hasOwnProperty(key)) continue;
for (let x of obj[key])
if (x.label.length > longest)
longest = x.label.length;
console.log(longest);
【讨论】:
谢谢,我怎样才能让它与有空格的标签一起工作? 我收到以下错误:Uncaught TypeError: Cannot use 'in' operator to search 'label' in Calculate Your Total @Mandalina 恐怕我无能为力,因为此错误是由您自己的代码引起的...如果您单击问题中的“运行代码 sn-p”蓝色按钮,它是清除我的代码工作正常。 你好@cybernaut 我再次补充了这个问题,这对于包含对象和数组的对象如何工作? @Mandalina 对不起,每个问题一个问题!你必须问一个新的(你可以把它链接到这个,我会看看)。【参考方案2】:您可以使用这 1 行语句。
let maxLen = Math.max(...Object.keys(obj).map((key) => Math.max(...obj[key].map((o) => o.label.length))));
节点 REPL 示例
> var obj =
... "array1": [
...
..... "label": "something1",
..... "ref": "option2a"
..... ,
...
..... "label": "something2",
..... "ref": "option2b"
..... ,
...
..... "label": "something3",
..... "ref": "option2a"
..... ,
...
..... "label": "something4",
..... "ref": "option2a"
..... ,
...
..... "label": "something5",
..... "ref": "option2a"
.....
... ],
... "array2": [
...
..... "label": "somethinglongest",
..... "ref": "option3a"
..... ,
...
..... "label": "Other",
..... "ref": "option3b"
.....
... ]
...
undefined
>
> Math.max(...Object.keys(obj).map((key) => Math.max(...obj[key].map((o) => o.label.length))))
16
>
详细概述
let keys = Object.keys(obj);
let maxLens = keys.map((key) =>
let arr = obj[key];
return Math.max(...arr.map((o) => o.label.length))
);
let max = Math.max(...maxLens);
console.log(keys); // [ 'array1', 'array2' ]
console.log(maxLens); // [ 10, 16 ]
console.log(max); // 16
这里有一个可以帮助你的例子。
> Math.max(4, 5, 7)
7
>
> Math.max([4, 5, 7])
NaN
>
> Math.max(...[6, 7])
7
>
> let a = [2, 4, 5]
undefined
>
> a2 = a.map((num) => num ** 2)
[ 4, 16, 25 ]
>
> a3 = a.map((num) => num + 2)
[ 4, 6, 7 ]
>
【讨论】:
非常感谢您的回答!我已更新问题以包含其中包含空格的标签。你能告诉我这将如何工作以包含更新吗?我喜欢步行。 所以在这种情况下,相同的代码可以工作,但它也会计算空格。你想跳过空格还是可以?谢谢。【参考方案3】:您可以查找对象,然后查找所需的密钥。这适用于任意深度的数据。
function getLongest(object, key)
return Object.values(object).reduce((l, v) =>
if (key in v) return Math.max(l, v[key].length);
if (v && typeof v === 'object') return Math.max(l, getLongest(v, key));
return l;
, 0);
var data = array1: [ label: "something1", ref: "option2a" , label: "something2", ref: "option2b" , label: "something3", ref: "option2a" , label: "something4", ref: "option2a" , label: "something5", ref: "option2a" ], array2: [ label: "somethinglongest", ref: "option3a" , label: "Other", ref: "option3b" ] ;
console.log(getLongest(data, 'label'));
【讨论】:
【参考方案4】:获取子数组中所有对象的数组。
计算将每个值映射到其长度的值的最大长度:
var obj =
"array1": [
"label": "something1",
"ref": "option2a"
,
"label": "something2",
"ref": "option2b"
,
"label": "something3",
"ref": "option2a"
,
"label": "something4",
"ref": "option2a"
,
"label": "something5",
"ref": "option2a"
],
"array2": [
"label": "somethinglongest",
"ref": "option3a"
,
"label": "Other",
"ref": "option3b"
]
;
console.log(Math.max(...Object.values(obj).flat().map(o => o.label.length)));
【讨论】:
+1 表示flat
方法。你可以不用减少Math.max(...Object.values(obj).flat().map(o => o.label.length))
希望具有建设性——为什么要在 1 行中执行这么多操作?乍一看或者以后回来调整时,这不是很难理解吗?
@CharlieSchliesser 只是因为我打字速度更快并且一次完成。但是任何人都可以提取他想要的所有变量:)【参考方案5】:
另一种选择是遍历obj
对象自己的属性,并检查每个标签的长度是否比之前的最长长度长。
var obj =
"array1": [
"label": "something1", "ref": "option2a" ,
"label": "something2", "ref": "option2b" ,
"label": "something3", "ref": "option2a" ,
"label": "something4", "ref": "option2a" ,
"label": "something5", "ref": "option2a"
], "array2": [
"label": "somethinglongest", "ref": "option3a" ,
"label": "Other", "ref": "option3b"
]
let longest = 0;
for (key in obj)
if(obj.hasOwnProperty(key))
obj[key].forEach(item =>
if (item.label.length > longest) longest = item.label.length;
)
console.log(longest);
【讨论】:
【参考方案6】: 使用.concat()
和Object.values()
获取包含所有对象的单个数组。
对包含字符串长度的数组使用.map()
。
最后使用.reduce()
得到最长字符串的长度。
let data =
"array1": [
"label": "something1", "ref": "option2a",
"label": "something2", "ref": "option2b",
"label": "something3", "ref": "option2a",
"label": "something4", "ref": "option2a",
"label": "something5", "ref": "option2a"
],
"array2": [
"label": "somethinglongest", "ref": "option3a",
"label": "Other", "ref": "option3b"
]
;
let reducer = arr => [].concat(...Object.values(arr))
.map(( label ) => label.length)
.reduce((r, c) => r > c ? r : c);
console.log(reducer(data));
【讨论】:
易读性在这里很有帮助。以上是关于对象数组的对象。获取具有相同属性的所有值的长度的主要内容,如果未能解决你的问题,请参考以下文章
如何从对象数组中获取具有属性的列表,除非它包含具有特定值的另一个项目?
JavaScript 利用new Set()抽离数组中所有具备相同属性值的对象.
JavaScript 利用new Set()抽离数组中所有具备相同属性值的对象.