typescript - JavaScript: ორი მასივის SQL-ს მსგავსი მიჯაჭვა
მე მაქვს ასეთ მასივები:
const one = [
{id: 1, field1: "a"},
{id: 2, field1: "b"},
{id: 3, field1: "c"},
{id: 4, field1: "d"}
]
const two = [
{id: 4, field2: "4"},
{id: 1, field2: "1"}
]
// what I want to achieve:
const result = [
{id: 1, field1: "a", field2: "1"},
{id: 4, field1: "d", field2: "4"}
]
მინდა გავაერთიანო ერთი და ორი, რათა მივიღო შედეგი. ეს ძალიან ჰგავს SQL join-ს, მაგრამ მინდა ეს ყველაფერი გავაკეთო JavaScript კოდში. ყურადღება მიაქციეთ:
- ეს არის „შეუერთება“
id„სვეტით." - შედეგის თანრიგი ემთხვევა
oneმასივის თანრიგს (საიდუმლოდ იდენტიფიკაციის მიხედვით დასორტირება მხოლოდ შემთხვევითად ემთხვევა ერთსა და იმავე თანრიგს) - ორივე მასივის ველები შედეგზე არსებობს
მე მივხვდი, როგორ გავაკეთო ეს თავად, მაგრამ კოდი რთული და ჭრელია. ძირითადად, თქვენ ფილტრავთ one-ზე და წაშლით ელემენტებს, რომლებიც two-ში არ არსებობენ, შემდეგ one-ზე აკეთებთ მეპინგს და ერთვებთ two მასივის ფრონტებს.
არსებოდება უფრო მოკლე გზა ამის მისაღწევად? მე ვიყენებ lodash-ს, და იმედოვნებდა, რომ იქ იქნებოდა ფუნქცია, რომელიც ამას გაამარტივებდა, მაგრამ მე არაფერს გამოვნახე.
პასუხი #1
შექმენით ლექსიკონი ან Map მეორე მასივის გასაღებით (id), და შემდეგ გააფილტრეთ პირველი მასივი, დატოვეთ მხოლოდ ის ელემენტები, რომლებიც არის ლექსიკონში. ამის შემდეგ, გააკეთეთ დარჩენილი ელემენტების მაპინგი და დაამატეთ შესაბამისი ელემენტები ლექსიკონიდან.
const joinBy = (arr1, arr2, key) => {
const arr2Dict = _.keyBy(arr2, key)
return arr1
.filter(item => item[key] in arr2Dict)
.map(item => ({ ...item, ...arr2Dict[item[key]] }))
}
const one = [{id: 1, field1: "a"},{id: 2, field1: "b"},{id: 3, field1: "c"},{id: 4, field1: "d"}]
const two = [{id: 4, field2: "4"},{id: 1, field2: "1"}];
const result = joinBy(one, two, 'id')
console.log(result)<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>თუ არ გსურთ lodash-ის გამოყენება, შეგიძლიათ მარტივად შეცვალოთ _.keyBy() და შექმნათ ობიექტი Array.reduce()-ის გამოყენებით ან შექმნათ Map Array.map()-ის გამოყენებით.
const joinBy = (arr1, arr2, key) => {
const arr2Dict = new Map(arr2.map(o => [o[key], o]))
return arr1
.filter(item => arr2Dict.has(item[key]))
.map(item => ({ ...item, ...arr2Dict.get(item[key]) }))
}
const one = [{id: 1, field1: "a"},{id: 2, field1: "b"},{id: 3, field1: "c"},{id: 4, field1: "d"}]
const two = [{id: 4, field2: "4"},{id: 1, field2: "1"}];
const result = joinBy(one, two, 'id')
console.log(result)<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>პასუხი #2
თქვენ შეგიძლიათ გამოიყენოთ merge, map და find ფუნქციები lodash-დან. სორტირებისათვის - sortBy.
_.sortBy(
_.map(two, (n) => _.merge(n, _.find(one, ['id', n.id]))),
(o) => _.findIndex(one, ['id', o.id]),
);
const one = [{id: 1, field1: "a"},{id: 2, field1: "b"},{id: 3, field1: "c"},{id: 4, field1: "d"}], two = [{id: 4, field2: "4"},{id: 1, field2: "1"}];
const r = _.sortBy(
_.map(two, (n) => _.merge(n, _.find(one, ['id', n.id]))),
(o) => _.findIndex(one, ['id', o.id]),
);
console.log(r);<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>