การรวมชุดข้อมูลที่ทับซ้อนกัน

เนื่องจากชุดข้อมูลหลายชุดที่อาจ/อาจไม่ทับซ้อนกันในหนึ่งคอลัมน์ขึ้นไป ฉันกำลังมองหาที่จะรวมชุดข้อมูลเข้าด้วยกันแบบไดนามิก

มีไลบรารีหรือข้อมูลโค้ดที่จะรวมชุดข้อมูลในลักษณะนี้หรือไม่ แค่ใช้คอลัมน์เดียวเป็นคีย์ล่ะ?

ตัวอย่าง: การรวมชุดข้อมูลสองชุดโดยใช้หลายคอลัมน์เป็นคีย์ (BookTitle, Author)

อินพุต ชุดข้อมูล 1

BookTitle, Author, Publisher
title1, author1, publisher1
title2, author2, publisher2
title3, author3, publisher3

อินพุต ชุดข้อมูล 2

BookTitle, Author, NumPages
title4, author4, numPages4
title7, author7, numPages7
title5, author5, numPages5
title3, author33, numPages3
title2, author2, numPages2

เอาท์พุต, ชุดข้อมูลที่เสียหาย

BookTitle, Author, Publisher, NumPages
title1, author1, publisher1, _null_
title2, author2, publisher2, numPages2
title3, author3, publisher3, _null_
title4, author4, _null_, numPages4
title5, author5, _null_, numPages5
title7, author7, _null_, numPages7
title3, author33, _null_, numPages3

ฉันได้ทำการวิจัยแล้ว แต่ก็ไม่มีประโยชน์อะไรเกิดขึ้นทันที (ส่วนใหญ่เกี่ยวกับการผสานออบเจ็กต์ JSON ในโครงสร้างเดียวกันเพียงครั้งเดียว (เช่น การต่อท้ายข้อมูล ซึ่งตรงข้ามกับการรวมชุดข้อมูลที่แตกต่างกัน)

ฉันกำลังมองหา Java/JavaScript โดยใช้ข้อมูล JSON/XML/CSV (ตามลำดับที่ต้องการ) แต่จะยอมรับภาษาอื่นโดยสมมติว่าอัลกอริทึมเหล่านั้นสามารถย้ายพอร์ตได้

ฉันจะพิจารณายอมรับตัวอย่างที่ทำในคอลัมน์เดียวเท่านั้น


person kwah    schedule 26.07.2014    source แหล่งที่มา


คำตอบ (1)


ฉันจะไม่มองหาห้องสมุดสำหรับสิ่งที่เรียบง่ายขนาดนี้จริงๆ ให้ลองสร้างวิธีแก้ปัญหาด้วยตัวเองแทน

ก่อนอื่นคุณสามารถ JSON.parse() สตริงใดๆ เพื่อแปลงให้เป็นวัตถุได้ จากนั้น คุณสามารถส่งวัตถุทั้งสองนี้ไปยังฟังก์ชันที่มีลักษณะดังนี้ได้

function mergeSets(first, second) {
    var result = first;
    second.forEach(function (item, index, array) {
        var resultIndex = contains(result, item);
        if (resultIndex === -1) {
            result.push(item);
        } else {
            result[resultIndex].numPages = item.numPages;
        }
    });
    return result;
}

โปรดสังเกตว่า mergeSets() เรียก contains() ซึ่งโดยพื้นฐานแล้วจะเป็นดังนี้

function contains(set, object) {
    var solution = -1;
    set.forEach(function (item, index, array) {
        if (item.bookTitle == object.bookTitle && item.author == object.author) {
            solution = index;
        }
    });
    return solution;
}

มันไม่ยากเกินไปอย่างที่คุณเห็น ขออภัยสำหรับชื่อตัวแปรบางส่วน เรื่องนี้เขียนอย่างเร่งรีบ นอกจากนี้ คุณยังกล่าวถึงในตัวอย่างชุดผลลัพธ์ที่คุณต้องการให้ฟิลด์ที่ไม่พร้อมใช้งานแสดงเป็น null ซึ่งไม่เหมาะสมเนื่องจาก null มักจะระบุถึงการอ้างอิงที่ว่างเปล่า แต่ฉันกลับเพิกเฉยต่อพวกเขา การเข้าถึงฟิลด์เหล่านั้นบนออบเจ็กต์ในอาร์เรย์ที่ไม่มีจะส่งผลให้ undefined ซึ่งสมเหตุสมผลดี

นอกจากนี้ ต่อไปนี้เป็นข้อจำกัดของโค้ดในซอ คุณสามารถแก้ไขได้เพื่อลดข้อจำกัดเหล่านี้และทำให้มีประสิทธิภาพมากขึ้น

  1. มันเชื่อมโยงกับรูปแบบข้อมูลที่คุณกล่าวถึงในคำถามของคุณ เพื่อให้ใช้งานได้กับชุดที่กำหนดเอง คุณสามารถตรวจสอบการมีอยู่ของคุณสมบัติโดยใช้ Object.hasOwnProperty() ในลูป for-in และเพิ่มคุณสมบัติที่จำเป็นซึ่งทำให้เกิดการรวมเข้าด้วยกัน

  2. มันไม่ได้จัดการรายการที่ซ้ำกันภายในเซตอยู่แล้ว

http://jsfiddle.net/x5Q5g/

แก้ไข: โอ้! อีกอย่าง โค้ดคือ JavaScript และรูปแบบข้อมูลอาจเป็น JSON หากคุณใช้ JSON.parse() และ JSON.stringify()

แก้ไข: การอัปเดตต่อไปนี้จะลบล้างข้อจำกัดแรกที่กล่าวถึงข้างต้น โปรดสังเกตว่าคุณต้องส่งคีย์เพื่อเปรียบเทียบอย่างชัดเจน

function contains(set, object, key) {
    var solution = -1;
    set.forEach(function (item, index, array) {
        if (item[key] === object[key]) {
            solution = index;
        }
    });
    return solution;
}

function mergeSets(first, second, key) {
    var result = first;
    second.forEach(function (item, index, array) {
        var resultIndex = contains(result, item, key);
        if (resultIndex === -1) {
            result.push(item);
        } else {
            result[resultIndex].numPages = item.numPages;
            for (var property in item) {
                if (item.hasOwnProperty(property)) {
                    if (!result[resultIndex].hasOwnProperty(property)) {
                        result[resultIndex].property = item.property;
                    }
                }
            }
        }
    });
    return result;
}

var solution = mergeSets(firstSet, secondSet, "bookTitle");
console.log(solution);

http://jsfiddle.net/s6HqL/

การอัปเดตครั้งสุดท้าย: ต่อไปนี้คือวิธีที่คุณสามารถกำหนดให้ระบบยอมรับคีย์จำนวนเท่าใดก็ได้ ฉันลืมไปว่าคุณต้องการการสนับสนุนหลายคีย์ ขอโทษ!

คุณต้องเปลี่ยนสิ่งต่อไปนี้

function contains(set, object, keys) {
    var solution = -1;
    set.forEach(function (item, index, array) {
        var selfItem = item;
        var allKeys = keys.every(function (item, index, array) {
            if (selfItem[item] === object[item]) {
                return true;
            }
        });
        if (allKeys) {
            solution = index;
        }
    });
    return solution;
}

function mergeSets(first, second) {
    var result = first;
    var keys = Array.prototype.slice.call(arguments, 2);
    second.forEach(function (item, index, array) {
        var resultIndex = contains(result, item, keys);
        if (resultIndex === -1) {
            result.push(item);
        } else {
            for (var property in item) {
                if (item.hasOwnProperty(property)) {
                    if (!result[resultIndex].hasOwnProperty(property)) {
                        var hello = result[resultIndex];
                        hello[property] = item[property];
                    }
                }
            }
        }
    });
    return result;
}

var solution = mergeSets(firstSet, secondSet, "bookTitle", "author");
console.log(solution);

http://jsfiddle.net/s6HqL/3/

ซอและโค้ดด้านบนนี้เสร็จสมบูรณ์แล้ว ไร้ซึ่งการอ้างอิง! และเป็นเรื่องทั่วไป จะทำงานกับคีย์จำนวนเท่าใดก็ได้เป็นอาร์กิวเมนต์

person Siddharth    schedule 26.07.2014
comment
ดูเหมือนเป็นจุดเริ่มต้นที่น่าสนใจ ขอบคุณ ส่วนที่โซลูชันนี้ไม่ได้รับการแก้ไขคือโครงสร้างของชุดข้อมูลและคอลัมน์ที่จะรวมชุดข้อมูลเหล่านี้เป็นแบบไดนามิก (เช่น ไม่ทราบจนกว่าจะรันไทม์ / จัดทำโดยผู้ใช้) อาจเป็นกรณีของการดึงสิ่งเหล่านี้ออกมาเป็นพารามิเตอร์ .. ? - person kwah; 26.07.2014
comment
สายเกินไปที่จะแก้ไขความคิดเห็นของฉัน แต่ความคิดเห็น 'ไลบรารี' มีวัตถุประสงค์เพื่อเป็นคำใบ้ว่าฉันกำลังมองหาบางสิ่งทั่วไป ซึ่งตรงข้ามกับการเขียนโค้ดไปยังชุดข้อมูลเฉพาะ ฉันจะดูการแก้ไขคำถามให้ชัดเจนยิ่งขึ้น :) - person kwah; 26.07.2014
comment
ให้ฉันแก้ไขโซลูชันของฉันและทำให้มันเป็นแบบทั่วไปสำหรับคุณ เดี๋ยว. - person Siddharth; 26.07.2014
comment
ฉันโหวตให้คุณแล้ว แต่เนื่องจากยังไม่สมบูรณ์ ฉันจึงลังเลที่จะทำเครื่องหมายว่าเป็นคำตอบที่ถูกต้อง (เช่น ยังมีการอ้างอิงถึง .numPages) ฉันจะมีการเล่นเพื่อให้ยังคงทั่วไปมากขึ้น สมมติว่าไม่มีการโพสต์คำตอบที่สมบูรณ์กว่านี้ในระหว่างนี้ ฉันยินดีที่จะทำเครื่องหมายว่าถูกต้องเมื่อฉันทำเสร็จแล้ว (และแบ่งปันซอกลับ) เพราะคุณจะช่วยได้มาก :) - person kwah; 26.07.2014
comment
อ๊ะ. ฉันลืมเอาบรรทัดนั้นออก มันทำงานได้โดยไม่มีมัน! คุณไม่จำเป็นต้องอ้างอิงถึง numPages ตรวจสอบซอครั้งสุดท้าย - person Siddharth; 26.07.2014
comment
โอ้ เยี่ยมเลย ไชโย! ยอมรับเมื่อคุณตอบคำถามที่ฉันถาม! :) คุณสมควรได้รับมากกว่าตัวแทนที่โหวตเห็นด้วย/ยอมรับเพียงคนเดียวสำหรับการตอบกลับและให้ความช่วยเหลือ! - person kwah; 26.07.2014
comment
อา. ไม่ต้องกังวลเกี่ยวกับมัน ยินดีต้อนรับเสมอ นี่คือสิ่งที่เว็บไซต์นี้เป็นข้อมูลเกี่ยวกับ - person Siddharth; 26.07.2014