如何在javascript中做LINQ SelectMany()的等效物

2022-08-30 04:53:27

不幸的是,我没有JQuery或Underscore,只有纯javascript(IE9兼容)。

我想要来自LINQ功能的SelectMany()的等效物。

// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);

我能做到吗?

编辑:

多亏了答案,我得到了这个工作:

var petOwners = 
[
    {
        Name: "Higa, Sidney", Pets: ["Scruffy", "Sam"]
    },
    {
        Name: "Ashkenazi, Ronen", Pets: ["Walker", "Sugar"]
    },
    {
        Name: "Price, Vernette", Pets: ["Scratches", "Diesel"]
    },
];

function property(key){return function(x){return x[key];}}
function flatten(a,b){return a.concat(b);}

var allPets = petOwners.map(property("Pets")).reduce(flatten,[]);

console.log(petOwners[0].Pets[0]);
console.log(allPets.length); // 6

var allPets2 = petOwners.map(function(p){ return p.Pets; }).reduce(function(a, b){ return a.concat(b); },[]); // all in one line

console.log(allPets2.length); // 6

答案 1

对于简单的选择,您可以使用数组的减少函数。
假设您有一个数字数组数组:

var arr = [[1,2],[3, 4]];
arr.reduce(function(a, b){ return a.concat(b); }, []);
=>  [1,2,3,4]

var arr = [{ name: "name1", phoneNumbers : [5551111, 5552222]},{ name: "name2",phoneNumbers : [5553333] }];
arr.map(function(p){ return p.phoneNumbers; })
   .reduce(function(a, b){ return a.concat(b); }, [])
=>  [5551111, 5552222, 5553333]

编辑:
由于es6 flatMap已被添加到数组原型中。 是 的同义词。
该方法首先使用映射函数映射每个元素,然后将结果平展到一个新数组中。它在TypeScript中的简化签名是:SelectManyflatMap

function flatMap<A, B>(f: (value: A) => B[]): B[]

为了实现任务,我们只需要将每个元素平映射到电话号码

arr.flatMap(a => a.phoneNumbers);

答案 2

作为更简单的选项,Array.prototype.flatMap()Array.prototype.flat()

const data = [
{id: 1, name: 'Dummy Data1', details: [{id: 1, name: 'Dummy Data1 Details'}, {id: 1, name: 'Dummy Data1 Details2'}]},
{id: 1, name: 'Dummy Data2', details: [{id: 2, name: 'Dummy Data2 Details'}, {id: 1, name: 'Dummy Data2 Details2'}]},
{id: 1, name: 'Dummy Data3', details: [{id: 3, name: 'Dummy Data3 Details'}, {id: 1, name: 'Dummy Data3 Details2'}]},
]

const result = data.flatMap(a => a.details); // or data.map(a => a.details).flat(1);
console.log(result)