javascript - দুটি পদার্থ যুক্ত অ্যারে এর পার্থক্য এবং ছেদ



arrays set-intersection (5)

আপনার প্রথম প্রশ্নের (ছেদটি) উত্তর দেওয়ার জন্য এখানে আন্ডারস্কোর / লড্যাশ সহ একটি ফাংশনাল প্রোগ্রামিং সমাধান রয়েছে।

list1 = [ {userId:1234,userName:'XYZ'}, 
          {userId:1235,userName:'ABC'}, 
          {userId:1236,userName:'IJKL'},
          {userId:1237,userName:'WXYZ'}, 
          {userId:1238,userName:'LMNO'}
        ];

list2 = [ {userId:1235,userName:'ABC'},  
          {userId:1236,userName:'IJKL'},
          {userId:1252,userName:'AAAA'}
        ];

_.reduce(list1, function (memo, item) {
        var same = _.findWhere(list2, item);
        if (same && _.keys(same).length === _.keys(item).length) {
            memo.push(item);
        }
        return memo
    }, []);

অন্যান্য প্রশ্নের উত্তর দেওয়ার জন্য আমি আপনাকে এটি উন্নত করতে দেব ;-)

https://src-bin.com

আমার দুটি অ্যারে list1 এবং list2 যার কিছু বৈশিষ্ট্য সহ অবজেক্ট রয়েছে; userId হ'ল আইডি বা অনন্য সম্পত্তি:

list1 = [
    { userId: 1234, userName: 'XYZ'  }, 
    { userId: 1235, userName: 'ABC'  }, 
    { userId: 1236, userName: 'IJKL' },
    { userId: 1237, userName: 'WXYZ' }, 
    { userId: 1238, userName: 'LMNO' }
]

list2 = [
    { userId: 1235, userName: 'ABC'  },  
    { userId: 1236, userName: 'IJKL' },
    { userId: 1252, userName: 'AAAA' }
]

আমি নিম্নলিখিত তিনটি অপারেশন কার্যকর করার একটি সহজ উপায় খুঁজছি:

  1. list1 operation list2 2 উপাদানগুলির ছেদটি ফিরিয়ে list1 operation list2 হবে:

    [
        { userId: 1235, userName: 'ABC'  },
        { userId: 1236, userName: 'IJKL' }
    ]
  2. list1 operation list2 তালিকা তালিকার মধ্যে উপস্থিত না থাকা তালিকা 1 থেকে সমস্ত উপাদানগুলির তালিকা ফিরিয়ে list2 :

    [
        { userId: 1234, userName: 'XYZ'  },
        { userId: 1237, userName: 'WXYZ' }, 
        { userId: 1238, userName: 'LMNO' }
    ]
  3. list2 operation list1 তালিকা 1 তালিকার 2 থেকে উপাদানগুলির তালিকা ফিরিয়ে list2 যা তালিকা 1 তে list1 :

    [
        { userId: 1252, userName: 'AAAA' }
    ]

Answer #1

আপনি inBoth , inFirstOnly এবং inSecondOnly তিনটি ফাংশন সংজ্ঞায়িত করতে পারেন যা সমস্ত আর্গুমেন্ট হিসাবে দুটি তালিকা গ্রহণ করে এবং ফাংশনটির নাম থেকে বোঝা যায় এমন একটি তালিকা ফিরিয়ে দেয়। তিনটি নির্ভর করে এমন একটি সাধারণ ফাংশন operation মূল যুক্তি যুক্ত করা যেতে পারে।

operation বেছে নেওয়ার জন্য এখানে কয়েকটি বাস্তবায়ন দেওয়া হয়েছে, যার জন্য আপনি আরও নীচে একটি স্নিপেট খুঁজে পেতে পারেন:

  • লুপগুলির for পুরানো জাভাস্ক্রিপ্ট সরল করুন
  • filter এবং some অ্যারে পদ্ধতি ব্যবহার করে তীর ফাংশন
  • একটি Set দিয়ে অপ্টিমাইজড লুকআপ

লুপগুলির for পুরানো সমতল

// Generic helper function that can be used for the three operations:        
function operation(list1, list2, isUnion) {
    var result = [];
    
    for (var i = 0; i < list1.length; i++) {
        var item1 = list1[i],
            found = false;
        for (var j = 0; j < list2.length && !found; j++) {
            found = item1.userId === list2[j].userId;
        }
        if (found === !!isUnion) { // isUnion is coerced to boolean
            result.push(item1);
        }
    }
    return result;
}

// Following functions are to be used:
function inBoth(list1, list2) {
    return operation(list1, list2, true);
}

function inFirstOnly(list1, list2) {
    return operation(list1, list2);
}

function inSecondOnly(list1, list2) {
    return inFirstOnly(list2, list1);
}

// Sample data
var list1 = [
    { userId: 1234, userName: 'XYZ'  }, 
    { userId: 1235, userName: 'ABC'  }, 
    { userId: 1236, userName: 'IJKL' },
    { userId: 1237, userName: 'WXYZ' }, 
    { userId: 1238, userName: 'LMNO' }
];
var list2 = [
    { userId: 1235, userName: 'ABC'  },  
    { userId: 1236, userName: 'IJKL' },
    { userId: 1252, userName: 'AAAA' }
];
  
console.log('inBoth:', inBoth(list1, list2)); 
console.log('inFirstOnly:', inFirstOnly(list1, list2)); 
console.log('inSecondOnly:', inSecondOnly(list1, list2)); 

filter এবং some অ্যারে পদ্ধতি ব্যবহার করে তীর ফাংশন

এটি কিছু ES5 এবং ES6 বৈশিষ্ট্য ব্যবহার করে:

// Generic helper function that can be used for the three operations:        
const operation = (list1, list2, isUnion = false) =>
    list1.filter( a => isUnion === list2.some( b => a.userId === b.userId ) );

// Following functions are to be used:
const inBoth = (list1, list2) => operation(list1, list2, true),
      inFirstOnly = operation,
      inSecondOnly = (list1, list2) => inFirstOnly(list2, list1);

// Sample data
const list1 = [
    { userId: 1234, userName: 'XYZ'  }, 
    { userId: 1235, userName: 'ABC'  }, 
    { userId: 1236, userName: 'IJKL' },
    { userId: 1237, userName: 'WXYZ' }, 
    { userId: 1238, userName: 'LMNO' }
];
const list2 = [
    { userId: 1235, userName: 'ABC'  },  
    { userId: 1236, userName: 'IJKL' },
    { userId: 1252, userName: 'AAAA' }
];
  
console.log('inBoth:', inBoth(list1, list2)); 
console.log('inFirstOnly:', inFirstOnly(list1, list2)); 
console.log('inSecondOnly:', inSecondOnly(list1, list2));

অপ্টিমাইজিং লুকআপ

নেস্টেড লুপের কারণে উপরের সমাধানগুলিতে একটি O (n²) সময় জটিলতা রয়েছে - some লুপকেও প্রতিনিধিত্ব করে। সুতরাং বড় অ্যারেগুলির জন্য আপনি ব্যবহারকারীর আইডিতে আরও একটি (অস্থায়ী) হ্যাশ তৈরি করতে চান। ফিল্টার কলব্যাক ফাংশন উত্পন্ন করবে এমন কোনও ফাংশনের যুক্তি হিসাবে একটি Set (ES6) সরবরাহ করে এটি অন-ফ্লাইয়ে করা যায়। এই ফাংশনটি তার সাথে ধ্রুবক সময়ে চেহারাটি সম্পাদন করতে পারে:

// Generic helper function that can be used for the three operations:        
const operation = (list1, list2, isUnion = false) =>
    list1.filter(
        (set => a => isUnion === set.has(a.userId))(new Set(list2.map(b => b.userId)))
    );

// Following functions are to be used:
const inBoth = (list1, list2) => operation(list1, list2, true),
      inFirstOnly = operation,
      inSecondOnly = (list1, list2) => inFirstOnly(list2, list1);

// Sample data
const list1 = [
    { userId: 1234, userName: 'XYZ'  }, 
    { userId: 1235, userName: 'ABC'  }, 
    { userId: 1236, userName: 'IJKL' },
    { userId: 1237, userName: 'WXYZ' }, 
    { userId: 1238, userName: 'LMNO' }
];
const list2 = [
    { userId: 1235, userName: 'ABC'  },  
    { userId: 1236, userName: 'IJKL' },
    { userId: 1252, userName: 'AAAA' }
];
  
console.log('inBoth:', inBoth(list1, list2)); 
console.log('inFirstOnly:', inFirstOnly(list1, list2)); 
console.log('inSecondOnly:', inSecondOnly(list1, list2));


Answer #2

কেবল filter এবং জেএসের some অ্যারে পদ্ধতি ব্যবহার করুন এবং আপনি এটি করতে পারেন।

let arr1 = list1.filter(e => {
   return !list2.some(item => item.userId === e.userId);
});

এটি list1 উপস্থিত নয় তবে তালিকায় নেই এমন list2 । আপনি যদি উভয় তালিকার সাধারণ আইটেমগুলি সন্ধান করছেন। শুধু এই কাজ।

let arr1 = list1.filter(e => {
   return list2.some(item => item.userId === e.userId); // take the ! out and you're done
});

Answer #3

lodash's _.isEqual পদ্ধতিটি ব্যবহার করুন। বিশেষ করে:

list1.reduce(function(prev, curr){
  !list2.some(function(obj){
    return _.isEqual(obj, curr)
  }) ? prev.push(curr): false;
  return prev
}, []);

উপরেরটি আপনাকে A given !B এর সমতুল্য দেয় (এসকিউএল পদগুলিতে, A LEFT OUTER JOIN B )। আপনি যা চান তা পেতে কোডের চারপাশে কোডটি সরিয়ে নিতে পারেন!


Answer #4
function intersect(first, second) {
    return intersectInternal(first, second, function(e){ return e });
}

function unintersect(first, second){
    return intersectInternal(first, second, function(e){ return !e });  
}

function intersectInternal(first, second, filter) {
    var map = {};

    first.forEach(function(user) { map[user.userId] = user; });

    return second.filter(function(user){ return filter(map[user.userId]); })
}





set-operations