按 javascript 中嵌套数组的索引过滤



我在javascript中有一个数组,其中包含许多嵌套数组

let data = [
["Apple","Fruit","Red"],
["Pear","Fruit","Green"],
["Orange","Fruit","Orange"],
["Carrot","Vegetable","Orange"],
["Pea","Vegetable","Green"],
["Pumpkin","Vegetable","Orange"]
]

从这个数组中,我希望创建两个新数组。Arr1是独特的食物类型(索引2),Arr2是独特的颜色(索引3)。

我的新数组应该是:

Arr1 = ["Fruit","Vegetable"]
Arr2 = ["Red","Green","Orange"]

我通过使用for each设法实现了这一点,其中我将每隔一个对象推送到数组中。然后,我过滤这个新数组以获取唯一值。这是我用来执行此操作的代码:

var Foods = []
var Colors = []
for (var key in data) {
Foods.push(data[key][1]);
}         

for (var key in data) {
Colors.push(data[key][2]);
}  

let Arr1 = [...new Set(Foods)]
let Arr2 = [...new Set(Colors)]

console.log(Arr1)
console.log(Arr2)

虽然这很好用,但作为一个 JavaScript 初学者,我认为可能有一种更优雅的方法来实现。

例如,是否无法过滤索引为 [2] 的数据的所有唯一值?

你的代码很好,唯一的改进是用map替换循环:

let foods  = [...new Set(data.map(d => d[1]))]
let colors = [...new Set(data.map(d => d[2]))]

绝对没有必要用reduce、解构等过于复杂化。

如果你想让它看起来稍微优雅一点,你可以定义两个实用程序函数

const item = i => a => a[i]
const uniq = a => [...new Set(a)]

然后

let foods  = uniq(data.map(item(1)))
let colors = uniq(data.map(item(2)))

另一种选择:

const uniq = a => [...new Set(a)]
const zip = (...args) => args[0].map((_, i) => args.map(a => a[i]))
let [_, foods, colors] = zip(...data).map(uniq)

将数组减少到两个集合,然后解构集合,并将每个集合分散到相应的数组中:

const data = [["Apple","Fruit","Red"],["Pear","Fruit","Green"],["Orange","Fruit","Orange"],["Carrot","Vegetable","Orange"],["Pea","Vegetable","Green"],["Pumpkin","Vegetable","Orange"]]
const [s1, s2] = data.reduce((acc, arr) => {
acc.forEach((s, i) => s.add(arr[i + 1]))
return acc
}, [new Set(), new Set()])
const Arr1 = [...s1]
const Arr2 = [...s2]
console.log({ Arr1, Arr2 })

您可以采用单个循环并获取嵌套数组的所有项目的唯一值。

const
getUnique = array => array
.reduce((r, a) => a.map((v, i) => (r[i] || new Set).add(v)), [])
.map(s => [...s]),
data = [["Apple", "Fruit", "Red"], ["Pear", "Fruit", "Green"], ["Orange", "Fruit", "Orange"], ["Carrot", "Vegetable", "Orange"], ["Pea", "Vegetable", "Green"], ["Pumpkin", "Vegetable", "Orange"]],
[, types, colors] = getUnique(data);

console.log(types);
console.log(colors);

创建一个以食物和颜色为键的对象,并在每次迭代中插入适当的元素索引

let data = [
["Apple","Fruit","Red"],
["Pear","Fruit","Green"],
["Orange","Fruit","Orange"],
["Carrot","Vegetable","Orange"],
["Pea","Vegetable","Green"],
["Pumpkin","Vegetable","Orange"]
]
const uniques = {
foods:new Set(),
colors: new Set()
}
data.forEach(a => uniques.foods.add(a[1]) && uniques.colors.add(a[2]) )
// just for demo logs
Object.entries(uniques).forEach(([k,set])=> console.log(k,':', ...set))

最新更新