ঠিক জাভাস্ক্রিপ্টে কীভাবে লিনকিউ সিলেক্টম্যানি () এর সমতুল্য কাজ করবেন


90

দুর্ভাগ্যক্রমে, আমার কাছে জিকিউরি বা ইন্ডোরস্কোর নেই, কেবল খাঁটি জাভাস্ক্রিপ্ট (আই 99 সামঞ্জস্যপূর্ণ)।

আমি লিনকিউ কার্যকারিতা থেকে সিলেক্টম্যান () এর সমতুল্য চাই।

// 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

4
এটি মোটেও দুর্ভাগ্যজনক নয়। খাঁটি জাভাস্ক্রিপ্ট আশ্চর্যজনক। প্রসঙ্গ ব্যতীত, আপনি এখানে কী অর্জন করতে চাইছেন তা বোঝা খুব শক্ত।
স্টার্লিং আর্চার

4
@ স্টার্লিংআরচার, উত্তরটি কতটা সুনির্দিষ্ট হয়েছে তা দেখুন। খুব বেশি সম্ভাব্য উত্তর ছিল না এবং সেরা উত্তরটি সংক্ষিপ্ত এবং সংক্ষিপ্ত ছিল।
টুডমো

উত্তর:


120

সাধারণ নির্বাচনের জন্য আপনি অ্যারের হ্রাস কার্যকারিতাটি ব্যবহার করতে পারেন।
বলুন আপনার কাছে সংখ্যার অ্যারে রয়েছে:

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 ফ্ল্যাটম্যাপটি অ্যারে প্রোটোটাইপে যুক্ত করা হয়েছে। SelectManyপ্রতিশব্দ হয় flatMap
পদ্ধতিটি প্রথমে ম্যাপিং ফাংশনটি ব্যবহার করে প্রতিটি উপাদানকে ম্যাপ করে, তারপরে ফলাফলটিকে নতুন অ্যারে রূপান্তর করে। টাইপস্ক্রিপ্টে এর সরলিকৃত স্বাক্ষরটি হ'ল:

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

কাজটি অর্জন করার জন্য আমাদের প্রতিটি উপাদানকে ফোন নম্বরগুলিতে ফ্ল্যাটম্যাপ করা দরকার

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

11
শেষটি হিসাবে লেখা যেতে পারেarr.reduce(function(a, b){ return a.concat(b.phoneNumbers); }, [])
টিমউই

আপনার .map () বা .concat () ব্যবহার করার দরকার নেই। আমার উত্তর নীচে দেখুন।
ওয়েসলিএএসি

এটি কি মূল অ্যারেটি পরিবর্তন করে না?
ইভান

এখনই কম গুরুত্বপূর্ণ, তবে flatMapএকটি IE9 সামঞ্জস্যপূর্ণ সমাধানের জন্য ওপির অনুরোধটি পূরণ করে না - ব্রাউজারের কমপ্যাটflatmap
রাফিন

24

একটি সহজ বিকল্প হিসাবে অ্যারে.প্রোটোটাইপ.ফ্ল্যাটম্যাপ () বা অ্যারে.প্রোটোটাইপ.ফ্ল্যাট ()

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)


4
সহজ এবং সংক্ষিপ্ত। এখন পর্যন্ত সেরা উত্তর।
স্টি ব্রাউন

এমডিএন অনুসারে 12/4/2019 পর্যন্ত ফ্ল্যাট () প্রান্তে উপলভ্য নয়।
পেটিস

তবে নতুন এজটি (ক্রোমিয়ামের উপর ভিত্তি করে) এটি সমর্থন করবে।
নেসিপ সানমাজ

4
দেখে মনে হচ্ছে অ্যারে.প্রোটোটাইপ.ফ্ল্যাটম্যাপ () এটিও একটি জিনিস, তাই আপনার উদাহরণটি আরও সরল করা যেতে পারেconst result = data.flatMap(a => a.details)
কাইল

12

কিছুক্ষণ পরে, জাভাস্ক্রিপ্ট বোঝার পরেও টাইপসক্রিপ্টে একটি সহজ টাইপড সিলেক্ট ম্যান পদ্ধতি চাই:

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>());
}

8

সাগি একটি অ্যারের সমতল করতে কনক্যাট পদ্ধতিটি ব্যবহার করে সঠিক। তবে এই উদাহরণের অনুরূপ কিছু পেতে, আপনার নির্বাচিত অংশ 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,[])

আমি '; আমি একটি ঝাঁকুনি করতে যাচ্ছি; আমি আপনার ডেটা জসন হিসাবে ব্যবহার করতে পারি। আপনার উত্তরটি এক লাইনের কোডের সমান করার চেষ্টা করবে। "কীভাবে ফ্ল্যাটিং অবজেক্ট হায়ারার্কি সম্পর্কে উত্তর
চ্যাপ্টা করা যায়

আপনার ডেটা ব্যবহারে নির্দ্বিধায় ... আমি মানচিত্রের ফাংশনটিকে স্পষ্টভাবে বিমূর্ত করেছি যাতে আপনি প্রতিবার নতুন ফাংশন না লিখে সহজেই কোনও সম্পত্তি নাম নির্বাচন করতে পারেন। কেবল arrসাথে peopleএবং এর "pets"সাথে প্রতিস্থাপন করুন"PhoneNumbers"
ফ্যাবিও বেলট্রামিনী

চ্যাপ্টা সংস্করণ দিয়ে আমার প্রশ্ন সম্পাদনা করেছে এবং আপনার উত্তরটি ভোট দিয়েছে। ধন্যবাদ
টুডমো

4
সাহায্যকারী ফাংশন আপ জিনিস পরিষ্কার না, কিন্তু ES6 সঙ্গে আপনি শুধু এটা করতে পারেন: petOwners.map(owner => owner.Pets).reduce((a, b) => a.concat(b), []);। বা, এমনকি সহজ petOwners.reduce((a, b) => a.concat(b.Pets), []);,।
এরিক

3
// 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),[])

=> [১, ২, ৪, "আসদা"]

ex2.reduce(selectMany(x=>x),[])

=> [১, ২, ৩, ৪, ৫]

ex3.reduce(selectMany(x=> "this will not be called" ),[])

=> []

ex4.reduce(selectMany(x=> x.nodes ),[])

=> ["1", "ভি"]

দ্রষ্টব্য: হ্রাস ফাংশনটিতে অন্তরঙ্গ মান হিসাবে বৈধ অ্যারে (নাল নন) ব্যবহার করুন


3

এটি চেষ্টা করুন (এস 6 সহ):

 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)

3

আমি এটি করতাম (.ccat () এড়ানো):

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;
}

4
আমি মনে করি এটি মজার যে আমি 4 বছর আগে এটি জিজ্ঞাসা করেছি এবং আপনার উত্তরের জন্য স্ট্যাক ওভারফ্লো বিজ্ঞপ্তিটি পপ আপ হয়ে গেছে এবং আমি এই মুহুর্তে যা করছি তা জেএস অ্যারের সাথে লড়াই করছে। চমৎকার পুনরাবৃত্তি!
টুডমো

আমি খুশি যে কেউ এটি দেখে! আমি অবাক হয়েছিলাম যে আমি লিখেছিলাম এমন কিছু ইতিমধ্যে তালিকাভুক্ত ছিল না, প্রদত্ত থ্রেডটি কত দিন চলেছে এবং কতগুলি উত্তর আছে সেগুলি দেওয়া হচ্ছে।
ওয়েসলিএএসি

@toddmo কি এটা এর মূল্য, আপনি যদি JS অ্যারে কাজ করছি ডান এখন, আপনি সমাধান আগ্রহী হতে পারে জন্য আমি সম্প্রতি এখানে যোগ করেছেন: stackoverflow.com/questions/1960473/...
ওয়েসলিএএসি

2

আপনি এখানে যান, কোনও এক্সটেনশান হিসাবে টাইপস্ক্রিপ্টে জোয়েল-হার্কসের উত্তরের পুনর্লিখিত সংস্করণ, কোনও অ্যারেতে ব্যবহারযোগ্য able সুতরাং আপনি আক্ষরিক এটি পছন্দ মতো ব্যবহার করতে পারেন somearray.selectMany(c=>c.someprop)। ট্রান্স-পাইলড, এটি জাভাস্ক্রিপ্ট।

declare global {
    interface Array<T> {
        selectMany<TIn, TOut>(selectListFn: (t: TIn) => TOut[]): TOut[];
    }
}

Array.prototype.selectMany = function <TIn, TOut>( selectListFn: (t: TIn) => TOut[]): TOut[] {
    return this.reduce((out, inx) => {
        out.push(...selectListFn(inx));
        return out;
    }, new Array<TOut>());
}


export { };

1

আপনি manipulaপ্যাকেজটি চেষ্টা করতে পারেন যা সমস্ত সি # লিনকিউ পদ্ধতি প্রয়োগ করে এবং এর সিনট্যাক্স সংরক্ষণ করে:

Manipula.from(petOwners).selectMany(x=>x.Pets).toArray()

https://github.com/litichevskiydv/manipula

https://www.npmjs.com/package/manipula


সুন্দর সমাধান!
toddmo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.