불행히도 JQuery 나 Underscore는없고 순수한 자바 스크립트 (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
답변
간단한 선택을 위해 Array의 축소 기능을 사용할 수 있습니다.
숫자 배열이 있다고 가정 해 보겠습니다.
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이 Array 프로토 타입에 추가 되었기 때문에.
SelectMany
의 동의어 flatMap
입니다.
이 메서드는 먼저 매핑 함수를 사용하여 각 요소를 매핑 한 다음 결과를 새 배열로 평면화합니다. TypeScript의 단순화 된 서명은 다음과 같습니다.
function flatMap<A, B>(f: (value: A) => B[]): B[]
작업을 수행하기 위해 각 요소를 phoneNumbers에 flatMap하면됩니다.
arr.flatMap(a => a.phoneNumbers);
답변
더 간단한 옵션으로 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)
답변
잠시 후 자바 스크립트를 이해하지만 Typescript에서 간단한 Typed SelectMany 메서드를 원합니다.
function selectMany<TIn, TOut>(input: TIn[], selectListFn: (t: TIn) => TOut[]): TOut[] {
return input.reduce((out, inx) => {
out.push(...selectListFn(inx));
return out;
}, new Array<TOut>());
}
답변
배열을 평면화하기 위해 concat 메서드를 사용하면 Sagi가 정확합니다. 그러나이 예제와 유사한 것을 얻으려면 선택 부분 https://msdn.microsoft.com/library/bb534336(v=vs.100).aspx에 대한 맵도 필요합니다.
/* arr is something like this from the example PetOwner[] petOwners =
{ new PetOwner { Name="Higa, Sidney",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi, Ronen",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price, Vernette",
Pets = new List<string>{ "Scratches", "Diesel" } } }; */
function property(key){return function(x){return x[key];}}
function flatten(a,b){return a.concat(b);}
arr.map(property("pets")).reduce(flatten,[])
답변
// you can save this function in a common js file of your project
function selectMany(f){
return function (acc,b) {
return acc.concat(f(b))
}
}
var ex1 = [{items:[1,2]},{items:[4,"asda"]}];
var ex2 = [[1,2,3],[4,5]]
var ex3 = []
var ex4 = [{nodes:["1","v"]}]
시작하자
ex1.reduce(selectMany(x=>x.items),[])
=> [1, 2, 4, “asda”]
ex2.reduce(selectMany(x=>x),[])
=> [1, 2, 3, 4, 5]
ex3.reduce(selectMany(x=> "this will not be called" ),[])
=> []
ex4.reduce(selectMany(x=> x.nodes ),[])
=> [ “1”, “v”]
참고 : reduce 함수에서 초기 값으로 유효한 배열 (null이 아님)을 사용하십시오.
답변
이것을 시도하십시오 (es6 사용) :
Array.prototype.SelectMany = function (keyGetter) {
return this.map(x=>keyGetter(x)).reduce((a, b) => a.concat(b));
}
예제 배열 :
var juices=[
{key:"apple",data:[1,2,3]},
{key:"banana",data:[4,5,6]},
{key:"orange",data:[7,8,9]}
]
사용 :
juices.SelectMany(x=>x.data)
답변
나는 이것을 할 것입니다 (.concat () 피하기) :
function SelectMany(array) {
var flatten = function(arr, e) {
if (e && e.length)
return e.reduce(flatten, arr);
else
arr.push(e);
return arr;
};
return array.reduce(flatten, []);
}
var nestedArray = [1,2,[3,4,[5,6,7],8],9,10];
console.log(SelectMany(nestedArray)) //[1,2,3,4,5,6,7,8,9,10]
.reduce ()를 사용하지 않으려면 :
function SelectMany(array, arr = []) {
for (let item of array) {
if (item && item.length)
arr = SelectMany(item, arr);
else
arr.push(item);
}
return arr;
}
.forEach ()를 사용하려면 :
function SelectMany(array, arr = []) {
array.forEach(e => {
if (e && e.length)
arr = SelectMany(e, arr);
else
arr.push(e);
});
return arr;
}