0

So I have a multidimensional array.
Each sub-array contains a value for IDs ... 1+ IDs separated by a hash.

array(
    array('name'=>'this', 'ids'=>'x'),
    array('name'=>'this', 'ids'=>'x#y'),
    array('name'=>'this', 'ids'=>'x#y#z'),
    array('name'=>'this', 'ids'=>'y'),
    array('name'=>'this', 'ids'=>'z#b#a'),
    array('name'=>'this', 'ids'=>'d'),
    array('name'=>'this', 'ids'=>'e'),
    array('name'=>'this', 'ids'=>'f#g'),
    array('name'=>'this', 'ids'=>'d#g')
)

Now, as you can see, some of those have an ID in common ... but sometimes it's multiple, other times just 1 out of n, or none.
What I need to do is add a Key to each child array, and have the same Key if they are related.

Thus;

array(
    array('key'=>'1', 'name'=>'this', 'ids'=>'x'),
    array('key'=>'1', 'name'=>'this', 'ids'=>'x#y'),
    array('key'=>'1', 'name'=>'this', 'ids'=>'x#y#z'),
    array('key'=>'2', 'name'=>'this', 'ids'=>'y'),
    array('key'=>'1', 'name'=>'this', 'ids'=>'z#b#a'),
    array('key'=>'3', 'name'=>'this', 'ids'=>'d'),
    array('key'=>'4', 'name'=>'this', 'ids'=>'e'),
    array('key'=>'3', 'name'=>'this', 'ids'=>'f#g'),
    array('key'=>'3', 'name'=>'this', 'ids'=>'d#g')
)

That way I can readily find all related/matching items.

Note : those entries with Key=3 ... ... that's the bit that is screwing me over. a simple foreach won't do the job. I've tried looping through the original array, looking to see if a Key is set, if not, create one ... then extract the IDs and assign them to a new array with that Key. but I never seem to catch the "backward move".

No - no code, as all I've managed so far is a straightforward foreach and new key->IDs array, which fails miserably.

I've searched around - but it seems there isn't anything that tackles this (which I find odd, as I would have thought it common for adding products to DBs etc.).

theclueless1
  • 123
  • 1
  • 1
  • 11
  • How should your script behave exactly if there is the same key twice? merge the "ids" or don't touch the first entry or override the first entry? – TiMESPLiNTER Oct 30 '13 at 09:57
  • Thanks for the response @TiMESPLiNTER . The idea is to end up with all associated/related **ids** pointing to the same **Key**. I shouldn't have to replace/delete ids (I could always clean that up later if needed). I have to keep each "row" as is, just with an addition so I can see they are related. – theclueless1 Oct 30 '13 at 10:09
  • Not 100% sure, but this [http://stackoverflow.com/questions/8839697/php-find-same-keys-in-a-multidimensional-array-and-merge-the-findings] looks close to what I'm after? – theclueless1 Oct 30 '13 at 10:12
  • I'm going to ask you why you chose this particular array structure to store your data: it seems cumbersome to me and a possible symptom of an XY problem. ( http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem ) Is this your case? – STT LCU Oct 30 '13 at 10:36
  • Hi there @STTLCU . That's not my structure - that's the base structure from a CSV file. The actual **problem** is one of logistical tracking - multiple possible IDs for parts that are technically the same (due to diff. supplier, manufacturer, purchase order, buy-in price etc.). My **problem** is to factor the variants and come up with multiple listings/entries, but with a parent ID to tie it all together with. Thus my CSV has an entry for PartNos and for Models and for Suppliers - each is slash separated if multiples exist. Thus I have to iterate through and explode etc. – theclueless1 Oct 30 '13 at 17:11
  • And @TiMESPLiNTER did a superb job of walking through it with me, and patching the code so that it not only finds all the related items, but assigns a "parent ID" to all related items. - Bonus cookie for TiMESPLiNTER :D – theclueless1 Oct 30 '13 at 17:13

1 Answers1

1

Okay, try this. Afterwards you have an array with each key once and an array of all ids but every id maximum once. You could implode() the ids array with # if you want a string again.

<?php

$data = array(
    array('name'=>'this', 'ids'=>'x'),
    array('name'=>'this', 'ids'=>'x#y'),
    array('name'=>'this', 'ids'=>'x#y#z'),
    array('name'=>'this', 'ids'=>'y'),
    array('name'=>'this', 'ids'=>'z#b#a'),
    array('name'=>'this', 'ids'=>'d'),
    array('name'=>'this', 'ids'=>'e'),
    array('name'=>'this', 'ids'=>'f#g'),
    array('name'=>'this', 'ids'=>'d#g')
);

$keyedData = array();

foreach($data as $k => $r) {
    $newArr = $r;
    $newArr['key'] = $k;
    $newArr['related_to'] = array();

    $idArr = explode('#', $r['ids']);

    foreach($idArr as $id) {
        foreach($data as $kkey => $kd) {
            if(strpos($kd['ids'], $id) === false)
                continue;

            $newArr['related_to'][] = $kkey;
        }

        $newArr['related_to'] = array_unique($newArr['related_to']);
    }

    $keyedData[] = $newArr;
}

echo'<pre>'; var_dump($keyedData);

/* EOF */
TiMESPLiNTER
  • 5,741
  • 2
  • 28
  • 64
  • Thank you @TiMESPLiNTER . That works perfectly when there is a Key. The problem I'm having is that I have to auto-assign Keys ... which is where I'm failing :( () – theclueless1 Oct 30 '13 at 10:47
  • But then you have no chance to determine to which record the keywords belong. – TiMESPLiNTER Oct 30 '13 at 10:49
  • That's the problem :D - I need to look through the array, if there is no **key**, I need to create one, assign it ... then look through the array for matching IDs. I think I need to create another array ($keys), and then build that with the KEY and the IDs ... then run that against the first array, and if the IDs are present, assign that Key... but I'm not 100% convinced that would work, nor quite how to do it :( – theclueless1 Oct 30 '13 at 10:53
  • But if the array has no keys at all. Every entry is a new key... you can not connect data. Your do you wanna know which "id" occurs in which keys? – TiMESPLiNTER Oct 30 '13 at 10:55
  • I've got "array keys" etc. But I need a value (called anything you like) that acts as a source/unique id that can be associated with multiple entries. This why I think I need to build a matrix first, then use that matrix to back-associated the unique key with the ids. - So I have to create KEy-1, look at the first item, attach those ids, then look at the next item, see if any of the firsts IDs match, if so, attach to the key, if not, create a new key and associate that to the second set of ids etc. – theclueless1 Oct 30 '13 at 10:59
  • - But ... that's when I hit the problem of key=>3 above, because the IDs show up in a perverse order, I may create a Key for an unknown ID, then find a corresponding ID later on... :( – theclueless1 Oct 30 '13 at 11:00
  • Alternatively ... do I build an array based on IDs, then try associating them? – theclueless1 Oct 30 '13 at 11:01
  • To understand you correct, please provide your code you have written so far. Yep that's what I asked you with the array of IDs. Your array is holding keys for you. They are numeric and the frist entry is 0, second 1 and so on. – TiMESPLiNTER Oct 30 '13 at 11:01
  • What's not to understand? I provided the data I have, and the data I need to create :( I'll run through some Undo's and see if I can dig out some of the not-working examples for you. – theclueless1 Oct 30 '13 at 11:07
  • Ah okay now I understand, I'll try to write a solution for you, I will you update in this comment. – TiMESPLiNTER Oct 30 '13 at 11:14
  • Thank you @TiMESPLiNTER - as this naff IDE I'm using doesn't seem to have more than 10 undo's :( – theclueless1 Oct 30 '13 at 11:17
  • Okay, check my edited code in the answer above. It saves the relations to a new array element "related_to" and uses the array keys from the original array. If you want to ensure that the key is always numeric and greater than 0 use array_values() before you use the data-array and add always +1 when you store a key anywhere. – TiMESPLiNTER Oct 30 '13 at 11:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/40249/discussion-between-theclueless1-and-timesplinter) – theclueless1 Oct 30 '13 at 11:32